package com.ssy.lingxi.purchase.serviceimpl.bidding;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.rabbitmq.client.Channel;
import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.constant.basic.EnableDisableStatus;
import com.ssy.lingxi.common.constant.manage.ShopEnvironmentEnum;
import com.ssy.lingxi.common.constant.manage.ShopTypeEnum;
import com.ssy.lingxi.common.constant.member.RoleTypeEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.common.utils.CollectionPageUtil;
import com.ssy.lingxi.common.utils.DateUtil;
import com.ssy.lingxi.component.rabbitMQ.constants.MessageConstants;
import com.ssy.lingxi.component.redis.service.IRedisStringUtils;
import com.ssy.lingxi.contract.api.feign.PurchaseViePriceControllerFeign;
import com.ssy.lingxi.contract.api.model.vo.request.PurchaseViePriceAddVO;
import com.ssy.lingxi.message.api.constant.MessageTemplateCode;
import com.ssy.lingxi.message.api.feign.SystemMessageControllerFeign;
import com.ssy.lingxi.message.api.vo.request.SystemMessageRequest;
import com.ssy.lingxi.platform.manage.api.feign.inner.ShopControllerFeign;
import com.ssy.lingxi.platform.manage.api.model.vo.shop.ShopVO;
import com.ssy.lingxi.platform.template.api.feign.inner.MemberPurchaseWebControllerFeign;
import com.ssy.lingxi.platform.template.api.model.dto.inner.MemberPurchaseInnerDTO;
import com.ssy.lingxi.purchase.api.common.OrderConstant;
import com.ssy.lingxi.purchase.api.common.PurchaseInquiryConstant;
import com.ssy.lingxi.purchase.api.dto.request.*;
import com.ssy.lingxi.purchase.api.dto.request.bidding.*;
import com.ssy.lingxi.purchase.api.dto.request.online.DiscardRequest;
import com.ssy.lingxi.purchase.api.dto.request.purchase.PurchaseListRequest;
import com.ssy.lingxi.purchase.api.dto.response.BiddingExternalWorkStateEnumResponse;
import com.ssy.lingxi.purchase.api.dto.response.CountryAreaResponse;
import com.ssy.lingxi.purchase.api.dto.response.bidding.*;
import com.ssy.lingxi.purchase.api.dto.response.online.CountryArea;
import com.ssy.lingxi.purchase.api.dto.response.online.OnlineBiddingListResponse;
import com.ssy.lingxi.purchase.api.dto.response.online.OnlineProductResponse;
import com.ssy.lingxi.purchase.api.dto.response.purchase.PurchaseListResponse;
import com.ssy.lingxi.purchase.api.dto.response.purchase.SearchReSourceDetailsResponse;
import com.ssy.lingxi.purchase.api.dto.response.purchase.SearchReSourceInstantaneousVO;
import com.ssy.lingxi.purchase.api.dto.response.purchase.SearchReSourceListResponse;
import com.ssy.lingxi.purchase.api.enums.bidding.*;
import com.ssy.lingxi.purchase.api.enums.notice.PurchaseNoticeTypeEnum;
import com.ssy.lingxi.purchase.api.enums.onlinebidding.OnlineAudteExternalStateEnum;
import com.ssy.lingxi.purchase.api.enums.onlinebidding.OnlineAudteInteriorStateEnum;
import com.ssy.lingxi.purchase.api.enums.onlinebidding.OnlineBiddingExternalWorkStateEnum;
import com.ssy.lingxi.purchase.api.enums.onlinebidding.OnlineInteriorWorkStateEnum;
import com.ssy.lingxi.purchase.api.enums.purchase.StatusEnum;
import com.ssy.lingxi.purchase.config.rabbitmq.OrderRbbitMqRequest;
import com.ssy.lingxi.purchase.config.rabbitmq.provider.RabbitMQProvider;
import com.ssy.lingxi.purchase.entity.bidding.*;
import com.ssy.lingxi.purchase.entity.notice.PurchaseNotice;
import com.ssy.lingxi.purchase.entity.onlinebidding.*;
import com.ssy.lingxi.purchase.entity.onlinebidding.OnLineBidding;
import com.ssy.lingxi.purchase.entity.onlinebidding.OnlineMateriel;
import com.ssy.lingxi.purchase.entity.onlinebidding.QOnLineBidding;
import com.ssy.lingxi.purchase.entity.quotedprice.QuotedPrice;
import com.ssy.lingxi.purchase.model.enums.ExternalLogTypeEnum;
import com.ssy.lingxi.purchase.repository.bidding.*;
import com.ssy.lingxi.purchase.repository.notice.PurchaseNoticeRepository;
import com.ssy.lingxi.purchase.repository.online.OnLineBiddingProductRepository;
import com.ssy.lingxi.purchase.repository.online.OnLineBiddingRepository;
import com.ssy.lingxi.purchase.repository.online.OnlineMaterielRepository;
import com.ssy.lingxi.purchase.service.bidding.BiddingService;
import com.ssy.lingxi.purchase.service.feign.IPurchaseMessageFeign;
import com.ssy.lingxi.purchase.service.online.OnlineBiddinService;
import com.ssy.lingxi.purchase.serviceimpl.BaseBiddingService;
import com.ssy.lingxi.purchase.utils.PurchaseUtils;
import com.ssy.lingxi.workflow.api.model.contant.ProcessEnum;
import com.ssy.lingxi.workflow.api.model.vo.response.SimpleTaskCompleteVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.modelmapper.ModelMapper;
import org.springframework.amqp.core.Message;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 采购竞价
 *
 * @author wrc
 * @date 2021/3/23
 */
@Slf4j
@Service
public class BiddingServiceImpl extends BaseBiddingService implements BiddingService {

    @Resource
    BiddingRepository biddingRepository;

    @Resource
    BiddingProductRepository biddingProductRepository;

    @Resource
    BiddingDemandMemberRepository biddingDemandMemberRepository;

    @Resource
    OnlineMaterielRepository onlineMaterielRepository;

    @Resource
    OnLineBiddingProductRepository productRepository;

    @Resource
    ExternalBiddingLogRepository externalBiddingLogRepository;

    @Resource
    SystemMessageControllerFeign systemMessageControllerFeign;

    @Resource
    JPAQueryFactory queryFactory;

    @Resource
    OnLineBiddingRepository onLineBiddingRepository;

    @Resource
    IRedisStringUtils redisStringUtils;

    @Resource
    RabbitMQProvider rabbitMQProvider;

    @Resource
    BiddingAreaRepository biddingAreaRepository;

    @Resource
    ShopControllerFeign shopControllerFeign;

    @Resource
    PurchaseViePriceControllerFeign purchaseViePriceControllerFeign;

    @Resource
    private IPurchaseMessageFeign purchaseMessageFeign;

    @Resource
    private OnlineBiddinService onlineBiddinService;

    @Resource
    private MemberPurchaseWebControllerFeign memberPurchaseWebControllerFeign;

    @Resource
    private PurchaseNoticeRepository purchaseNoticeRepository;
    /**
     * 创建线程池
     */
    private static final ExecutorService executor = new ThreadPoolExecutor(8, 16,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(1024),
            new BasicThreadFactory.Builder().namingPattern("BiddingServiceImpl-%d").daemon(true).build(),
            new ThreadPoolExecutor.AbortPolicy());

    /**
     * 采购竞价单查询
     */
    @Override
    public Wrapper<PageData<BiddingListResponse>> biddingList(BiddingListRequest request, UserLoginCacheDTO sysUser) {
        Wrapper<PageData<BiddingListResponse>> dataWrapper = getQuery(sysUser, request, BiddingListEnum.PURCHASE_BIDDING_LIST.getType());
        //外部状态为已完成不显示已作废
        List<BiddingListResponse> data = dataWrapper.getData().getData();
        if (!CollectionUtils.isEmpty(data)){
            data.forEach(biddingListResponse -> {
                if (!BiddingExternalWorkStateEnum.CANCEL.getState().equals(biddingListResponse.getExternalState()) &&
                        !BiddingExternalWorkStateEnum.COMPLETE.getState().equals(biddingListResponse.getExternalState())){
                    biddingListResponse.setButtons(Collections.singletonList(BiddingButtonEnums.CANCEL.getState()));
                }
            });
        }
        return dataWrapper;
    }

    /**
     * 采购竞价-采购竞价单详情
     */
    @Override
    public Wrapper<BiddingDetailsResponse> biddingDetails(BaseDetailsRequest request, UserLoginCacheDTO sysUser) {
        BiddingDetailsResponse response = new BiddingDetailsResponse();
        Bidding bidding;
        if (null != request.getId()) {
            bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        } else {
            bidding = biddingRepository.findByBiddingNoAndCreateMemberIdAndCreateMemberRoleId(request.getNumber(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        }
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        BeanUtils.copyProperties(bidding, response);

        response.setInteriorStateName(BiddingInteriorWorkStateEnum.getName(bidding.getInteriorState()));
        response.setExternalStateName(BiddingExternalWorkStateEnum.getName(bidding.getExternalState()));
        //适用区域
        response.setAreas(bidding.getAreas().stream().map(temp -> BeanUtil.copyProperties(temp, CountryAreaResponse.class)).collect(Collectors.toList()));
        Long id = bidding.getId();
        //查询采购竞价单物料信息列表
        response.setMateriels(getMateriels(id));
        //查询会员信息
        if (PurchaseInquiryConstant.type.INVITATION.equals(bidding.getType())) {
            response.setMembers(getBiddingMembers(id));
        }
        //查询采购竞价单内部流程记录
        response.setInteriorLogs(getBiddingInteriorLog(id));
        //查询采购竞价单内部流程状态图
        response.setInteriorLogStates(getLogStateInterior(ProcessEnum.PURCHASE_BIDDING_INTERIOR.getCode(), bidding.getInteriorNextStep()));
        //查询采购竞价单外部流程记录
        response.setExternalLogs(getExternalLog(id));
        //查询采购竞价单外部流程状态图
        response.setExternalLogStates(getLogStateExternal(ProcessEnum.PURCHASE_BIDDING_EXTERNAL.getCode(), bidding.getExternalNextStep(),null,bidding.getCreateMemberRoleId()));
        //审核竞价结果内部流转状态图
        response.setExamineInteriorLogStates(getLogStateInterior(ProcessEnum.PURCHASE_BIDDING_EXAMINE_INTERIOR.getCode(), bidding.getAuditInteriorNextStep()));
        //查询报名信息
        response.setSginUpInfos(getSginUpInfo(id));
        //授标结果
        response.setAwardsFruit(getAwardsFruits(id));
        //组装截止时间给前端
        response.setDays(0<=DateUtil.judgeTime(response.getBiddingEndTime())[0]?DateUtil.judgeTime(response.getBiddingEndTime())[0]:0);
        response.setHours(0<=DateUtil.judgeTime(response.getBiddingEndTime())[1]?DateUtil.judgeTime(response.getBiddingEndTime())[1]:0);
        response.setMinutes(0<=DateUtil.judgeTime(response.getBiddingEndTime())[2]?DateUtil.judgeTime(response.getBiddingEndTime())[2]:0);
        //查看竞价过程
        response.setAwardProcess(getAwardProcess(id));
        OnLineBidding onLineBidding = bidding.getOnLineBidding();
        if (Objects.isNull(onLineBidding)){
            return Wrapper.success(response);
        }
        //授标信息
        response.setPrizeNotice(onLineBidding.getPrizeNotice());
        response.setThank(onLineBidding.getThank());
        response.setNotice(onLineBidding.getNotice());
        response.setAwardResults(onLineBidding.getAwardResults());
        response.setContent(onLineBidding.getContent());
        response.setSignUpIdea(onLineBidding.getSignUpIdea());
        response.setReturnUrls(onLineBidding.getReturnUrls());
        response.setSumAwardPrice(onLineBidding.getSumAwardPrice());
        return Wrapper.success(response);
    }

    /**
     * 采购物料分页查询
     */
    @Override
    public Wrapper<PageData<BiddingProductRequest>> materielPage(BaseDetailsRequest request, UserLoginCacheDTO sysUser) {
        Bidding bidding;
        if (null != request.getId()) {
            bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        } else {
            bidding = biddingRepository.findByBiddingNoAndCreateMemberIdAndCreateMemberRoleId(request.getNumber(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        }
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        Long id = bidding.getId();
        Page<BiddingProduct> biddingProducts = biddingProductRepository.findAllByBiddingId(id, PageRequest.of(request.getCurrent(), request.getPageSize(), Sort.by("id").ascending()));
        long count = biddingProducts.getTotalElements();
        if (0 == count) {
            return Wrapper.success(new PageData<>(count, new ArrayList<>()));
        }
        List<BiddingProductRequest> collect = biddingProducts.getContent().stream().map(temp -> BeanUtil.copyProperties(temp, BiddingProductRequest.class)).collect(Collectors.toList());
        return Wrapper.success(new PageData<>(biddingProducts.getTotalElements(), collect));
    }

    /**
     * 需求对接会员列表分页查询
     */
    @Override
    public Wrapper<PageData<BiddingMemberResponse>> memberPage(BaseDetailsRequest request, UserLoginCacheDTO sysUser) {
        Bidding bidding;
        if (null != request.getId()) {
            bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        } else {
            bidding = biddingRepository.findByBiddingNoAndCreateMemberIdAndCreateMemberRoleId(request.getNumber(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        }
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        Long id = bidding.getId();
        Page<BiddingDemandMember> biddingMembers = biddingDemandMemberRepository.findAllByBiddingId(id, PageRequest.of(request.getCurrent(), request.getPageSize(), Sort.by("id").ascending()));
        long count = biddingMembers.getTotalElements();
        if (0 == count) {
            return Wrapper.success(new PageData<>(count, new ArrayList<>()));
        }
        List<BiddingMemberResponse> biddingMemberResponses = biddingMembers.stream().map(temp -> BeanUtil.copyProperties(temp, BiddingMemberResponse.class)).collect(Collectors.toList());
        return Wrapper.success(new PageData<>(biddingMembers.getTotalElements(), biddingMemberResponses));
    }

    /**
     * 报价明细
     */
    @Override
    public Wrapper<PageData<OnlineProductResponse>> quotedPriceDetaild(OnlineDetailsRequest request, UserLoginCacheDTO sysUser) {
        OnLineBidding onLineBiding = onLineBiddingRepository.findById(request.getOnlineBiddingId()).orElse(null);
        if (Objects.isNull(onLineBiding)){
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //根据报价单ID查询报价详情
        OnlineMateriel onlineMateriel = onlineMaterielRepository.findByOnlineBiddingAndCreateMemberIdAndCreateMemberRoleIdAndIsSignUp(onLineBiding, request.getMemberId(), request.getMemberRoleId(), StatusEnum.YES.getState());
        Page<OnLineBiddingProduct> products = productRepository.findByBiddingNoAndOnlineMateriel(onLineBiding.getBiddingNo(), onlineMateriel,PageRequest.of(request.getCurrent(), request.getPageSize(), Sort.by("id").ascending()));
        long count = products.getTotalElements();
        if (0 < count) {
            List<OnlineProductResponse> collect = products.get().map(temp -> BeanUtil.copyProperties(temp, OnlineProductResponse.class)).collect(Collectors.toList());
            return Wrapper.success(new PageData<>(count, collect));
        }
        return Wrapper.success(new PageData<>(count, new ArrayList<>()));
    }

    /**
     * 采购竞价单查询-作废
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Wrapper<Void> discard(DiscardRequest request, UserLoginCacheDTO sysUser) {
        //采购竞价单
        Bidding bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //外部状态为已完成的, 不能作废
        if (BiddingExternalWorkStateEnum.COMPLETE.getState().equals(bidding.getExternalState())){
            return Wrapper.fail(ResponseCode.PURCHASE_INQUIRY_PRICE_STATUS_IS_COMPLETE);
        }
        //外部状态为已作废的, 不能作废
        if (BiddingExternalWorkStateEnum.CANCEL.getState().equals(bidding.getExternalState())){
            return Wrapper.fail(ResponseCode.PURCHASE_INQUIRY_PRICE_DO_NOT_REPEAT);
        }
        bidding.setInteriorState(BiddingInteriorWorkStateEnum.CANCEL.getState());
        bidding.setExternalState(BiddingExternalWorkStateEnum.CANCEL.getState());
        bidding.setDiscardTime(request.getDiscardTime());
        bidding.setDiscardCause(request.getDiscardCaues());
        bidding.setUpdateTime(System.currentTimeMillis());
        biddingRepository.saveAndFlush(bidding);
        //在线竞价实体
        OnLineBidding onLineBidding = bidding.getOnLineBidding();
        if (Objects.nonNull(onLineBidding)){
            onLineBidding.setInteriorState(OnlineInteriorWorkStateEnum.CANCEL.getState());
            onLineBidding.setExternalState(OnlineBiddingExternalWorkStateEnum.CANCEL.getState());
            onLineBidding.setUpdateTime(System.currentTimeMillis());
            onLineBiddingRepository.saveAndFlush(onLineBidding);
            //供应商内部状态
            List<OnlineMateriel> materiels = onlineMaterielRepository.findAllByOnlineBiddingId(onLineBidding.getId());
            if (!CollectionUtils.isEmpty(materiels)){
                materiels.forEach(materiel ->{
                    materiel.setInteriorState(OnlineInteriorWorkStateEnum.CANCEL.getState());
                    materiel.setExternalState(OnlineBiddingExternalWorkStateEnum.CANCEL.getState());
                });
                onlineMaterielRepository.saveAll(materiels);
            }

            //采购单在线竞价单内部流转记录
            onlineBiddinService.initOnlineInteriorLog(sysUser, BiddingOperationStateEnum.CANCEL.getState(), onLineBidding.getInteriorState(), onLineBidding.getId(), request.getDiscardCaues());
        }
        //采购单内部流转记录
        saveInteriorLog(sysUser, BiddingOperationStateEnum.CANCEL.getState(), bidding.getInteriorState(), null, bidding.getId(), request.getDiscardCaues());
        //采购单外部流转记录
        saveExternalLog(sysUser, BiddingOperationStateEnum.CANCEL.getState(), bidding.getExternalState(), bidding.getId(), null,request.getDiscardCaues(), null, null);
        return Wrapper.success();
    }

    /**
     * 待新增采购竞价单
     */
    @Override
    public Wrapper<PageData<BiddingListResponse>> awaitNewList(BiddingListRequest request, UserLoginCacheDTO sysUser) {
        request.setShopType(ShopTypeEnum.PURCHASE.getCode());
        Wrapper<PageData<BiddingListResponse>> query = getQuery(sysUser, request, BiddingListEnum.ADD_PURCHASE_BIDDING_LIST.getType());
        if (ResponseCode.SUCCESS.getCode() == query.getCode() && query.getData().getTotalCount() > 0) {
            query.getData().getData().forEach(bidding -> {
                if (BiddingInteriorWorkStateEnum.STAY_SUBMIT_BIDDING.getState().equals(bidding.getInteriorState())) {
                    bidding.setButtons(Arrays.asList(BiddingButtonEnums.SUBMIT_REVIEW.getState(), BiddingButtonEnums.UPDATE.getState(), BiddingButtonEnums.DELETE.getState()));
                } else {
                    bidding.setButtons(Collections.singletonList(BiddingButtonEnums.UPDATE.getState()));
                }
            });
        }
        return query;
    }

    /**
     * 添加采购竞价单
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> add(BiddingAddRequest request, UserLoginCacheDTO sysUser, ModelMapper modelMapper) {
        long time = System.currentTimeMillis();
        //竞价开始时间不能大于竞价结束时间
       if(request.getBiddingStartTime()>=request.getBiddingEndTime()){
           return Wrapper.fail(ResponseCode.BIDDING_REPORT_PRICE_NOT_LOE);
       }
       //报名开始时间不能大于报名结束时间
        if(request.getStartSignUp()>=request.getEndSignUp()){
            return Wrapper.fail(ResponseCode.BIDDING_REPORT_NAME_NOT_LOE);
        }
        //报名结束时间不能大于竞价开始时间 且 报名开始时间要大于当前时间
        if(request.getEndSignUp() >= request.getBiddingStartTime()){
            return Wrapper.fail(ResponseCode.REPORT_NAME_NOT_REPORT_PRICE_LOE);
        }
        //判断报名时间必须大于当前时间
        if (time >= request.getStartSignUp()) {
            return Wrapper.fail(ResponseCode.REPORT_SIGN_TIME_NOT_CURRENT_TIME);
        }
        //采购会员是否创建采购门户
        MemberPurchaseInnerDTO purchaseInnerDTO = new MemberPurchaseInnerDTO();
        purchaseInnerDTO.setMemberId(sysUser.getMemberId());
        purchaseInnerDTO.setMemberRoleId(sysUser.getMemberRoleId());
        Wrapper<Boolean> result = memberPurchaseWebControllerFeign.exitMemberPurchase(purchaseInnerDTO);
        if (ResponseCode.SUCCESS.getCode() != result.getCode()){
            return Wrapper.fail(result.getMessage());
        }
        if (!result.getData()){
            return Wrapper.fail(ResponseCode.PURCHASE_PORTAL_NOT_CREATED);
        }
        Bidding bidding = new Bidding();

        //1. 初始化采购竞价单
        BeanUtils.copyProperties(request, bidding);
        bidding.setMinPrice(request.getIsMinPrice() == 0? 0D : request.getMinPrice());
        bidding.setBiddingNo(PurchaseUtils.randomUniqueNumber("JJ"));
        bidding.setCreateTime(System.currentTimeMillis());
        bidding.setUpdateTime(System.currentTimeMillis());
        bidding.setCreateMemberId(sysUser.getMemberId());
        bidding.setCreateMemberRoleId(sysUser.getMemberRoleId());
        bidding.setCreateMemberName(sysUser.getCompany());
        biddingRepository.saveAndFlush(bidding);

        //2. 保存适用地市信息
        List<BiddingArea> areas = request.getAreas().stream().map(area ->{
            BiddingArea biddingArea = BeanUtil.copyProperties(area, BiddingArea.class);
            biddingArea.setBidding(bidding);
            return biddingArea;
        }).collect(Collectors.toList());
        bidding.setAreas(areas);

        //3. 保存物料信息
        List<BiddingProduct> products = request.getMateriels().stream().map(area ->{
            BiddingProduct biddingProduct = BeanUtil.copyProperties(area, BiddingProduct.class);
            biddingProduct.setBidding(bidding);
            return biddingProduct;
        }).collect(Collectors.toList());
        bidding.setProducts(products);

        //4. 保存邀请人信息 (如果需求对接类型为指定供应会员)
        List<BiddingDemandMember> members;
        if (OrderConstant.DemandType.ASSIGN_MEMBER == request.getType()){
            members = request.getDemandMembers().stream().map(area ->{
                BiddingDemandMember demandMember = BeanUtil.copyProperties(area, BiddingDemandMember.class);
                demandMember.setBidding(bidding);
                return demandMember;
            }).collect(Collectors.toList());
            bidding.setMembers(members);
        }

        //5. 启动内部工作流
        Wrapper<SimpleTaskCompleteVO> taskResult = startWork(sysUser, bidding.getId(), ProcessEnum.PURCHASE_BIDDING_INTERIOR.getCode());
        if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
            throw new BusinessException(taskResult.getMessage());
        }
        bidding.setInteriorTaskId(taskResult.getData().getTaskId());
        bidding.setInteriorState(taskResult.getData().getStatus());
        bidding.setInteriorNextStep(taskResult.getData().getStep());
        //6. 启动外部工作流
        Wrapper<SimpleTaskCompleteVO> taskExternal = startWork(sysUser, bidding.getId(), ProcessEnum.PURCHASE_BIDDING_EXTERNAL.getCode());
        if (ResponseCode.SUCCESS.getCode() != taskExternal.getCode()) {
            throw new BusinessException(taskExternal.getMessage());
        }
        bidding.setExternalTaskId(taskExternal.getData().getTaskId());
        bidding.setExternalState(taskExternal.getData().getStatus());
        bidding.setExternalNextStep(taskExternal.getData().getStatus());
        biddingRepository.saveAndFlush(bidding);

        //保存内部流程记录
        saveInteriorLog(sysUser, BiddingOperationStateEnum.ADD.getState(), taskResult.getData().getStatus(), taskResult.getData().getStep(), bidding.getId(), "");

        //发送采购竞价消息
        purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_wait_audit);
        return Wrapper.success();
    }

    /**
     * 修改采购竞价单
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Wrapper<Void> update(BiddingUpdateRequest request, UserLoginCacheDTO sysUser, ModelMapper modelMapper) {
        Bidding bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //判断竞价单状态是否可以修改
        if (!isUpdate(bidding)) {
            return Wrapper.fail(ResponseCode.PURCHASE_CAN_NOT_UPDATE_BECAUSE_OF_STATUS_MISMATCH);
        }
        //1. 清除中间表关联信息
        clearBidding(bidding);

        //2. 保存适用地市信息
        List<BiddingArea> areas = request.getAreas().stream().map(area ->{
            BiddingArea biddingArea = BeanUtil.copyProperties(area, BiddingArea.class);
            biddingArea.setBidding(bidding);
            return biddingArea;
        }).collect(Collectors.toList());
        bidding.setAreas(areas);

        //3. 保存物料信息
        List<BiddingProduct> products = request.getMateriels().stream().map(area ->{
            BiddingProduct biddingProduct = BeanUtil.copyProperties(area, BiddingProduct.class);
            biddingProduct.setBidding(bidding);
            return biddingProduct;
        }).collect(Collectors.toList());
        bidding.setProducts(products);

        //4. 保存邀请人信息 (如果需求对接类型为指定供应会员)
        List<BiddingDemandMember> members;
        if (OrderConstant.DemandType.ASSIGN_MEMBER == request.getType()){
            members = request.getDemandMembers().stream().map(area ->{
                BiddingDemandMember demandMember = BeanUtil.copyProperties(area, BiddingDemandMember.class);
                demandMember.setBidding(bidding);
                return demandMember;
            }).collect(Collectors.toList());
            bidding.setMembers(members);
        }
        //5. 修改采购竞价单
        BeanUtils.copyProperties(request, bidding);
        bidding.setUpdateTime(System.currentTimeMillis());
        //内部状态为 待提交审核采购竞价单
        bidding.setInteriorState(BiddingInteriorWorkStateEnum.STAY_SUBMIT_BIDDING.getState());
        biddingRepository.saveAndFlush(bidding);

        //保存内部审核流程记录
        saveInteriorLog(sysUser, BiddingOperationStateEnum.UPDATE.getState(), bidding.getInteriorState(), bidding.getInteriorNextStep(), bidding.getId(), "");
        return Wrapper.success();
    }

    /**
     * 删除采购竞价单
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Wrapper<Void> delete(BaseRequest request, UserLoginCacheDTO sysUser) {
        Bidding bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //判断竞价单状态是否可以删除
        if (isDelete(bidding)) {
            return Wrapper.fail(ResponseCode.PURCHASE_NOT_DELETE);
        }
        biddingRepository.deleteById(bidding.getId());
        return Wrapper.success();
    }

    /**
     * 批量删除采购竞价单
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Wrapper<Void> deleteBatch(BaseAllRequest request, UserLoginCacheDTO sysUser) {
        List<Bidding> biddings = biddingRepository.findAllByCreateMemberIdAndCreateMemberRoleIdAndIdIn(sysUser.getMemberId(), sysUser.getMemberRoleId(), request.getIds());
        if (CollectionUtils.isEmpty(biddings)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        for (Bidding bidding : biddings) {
            if (ObjectUtils.isEmpty(bidding)) {
                return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
            }
            if (isDelete(bidding)) {
                return Wrapper.fail(ResponseCode.PURCHASE_NOT_DELETE);
            }
        }
        biddingRepository.deleteAll(biddings);
        return Wrapper.success();
    }

    /**
     * 采购竞价- 提交待审核采购竞价单
     */
    @Transactional
    @Override
    public Wrapper<Void> biddingExamine(BaseRequest request, UserLoginCacheDTO sysUser) {
        Bidding bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //内部状态为 待提交审核采购竞价单
        if (!BiddingInteriorWorkStateEnum.STAY_SUBMIT_BIDDING.getState().equals(bidding.getInteriorState())) {
            return Wrapper.fail(ResponseCode.PURCHASE_NOT_AUDIT);
        }
        //内部流程执行下一步工作流
        Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_INTERIOR.getCode(), bidding.getInteriorNextStep(), bidding.getInteriorTaskId(), OrderConstant.Auditing.DEFAULT);
        if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
            return Wrapper.fail(taskResult.getMessage());
        }
        bidding.setInteriorTaskId(taskResult.getData().getTaskId());
        bidding.setInteriorState(taskResult.getData().getStatus());
        bidding.setInteriorNextStep(taskResult.getData().getStep());
        //保存内部流转记录
        saveInteriorLog(sysUser, BiddingOperationStateEnum.SUBMIT_AUDIT_BIDDING.getState(), taskResult.getData().getStatus(), taskResult.getData().getStep(), bidding.getId(), "");
        biddingRepository.saveAndFlush(bidding);
        //发送采购竞价消息
        purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_audit_step_1);
        return Wrapper.success();
    }

    /**
     * 提交待审核采购竞价单- 批量
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Wrapper<Void> biddingExamineBatch(BaseAllRequest request, UserLoginCacheDTO sysUser) {
        List<Bidding> biddings = biddingRepository.findAllByCreateMemberIdAndCreateMemberRoleIdAndIdIn(sysUser.getMemberId(), sysUser.getMemberRoleId(), request.getIds());
        if (CollectionUtils.isEmpty(biddings)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        for (Bidding bidding : biddings) {
            if (ObjectUtils.isEmpty(bidding)) {
                return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
            }
            //内部状态为 待提交审核采购竞价单
            if (!BiddingInteriorWorkStateEnum.STAY_SUBMIT_BIDDING.getState().equals(bidding.getInteriorState())) {
                return Wrapper.fail(ResponseCode.PURCHASE_NOT_AUDIT);
            }
            //内部流程执行下一步工作流
            Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_INTERIOR.getCode(), bidding.getInteriorNextStep(), bidding.getInteriorTaskId(), OrderConstant.Auditing.DEFAULT);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                return Wrapper.fail(taskResult.getMessage());
            }
            bidding.setInteriorTaskId(taskResult.getData().getTaskId());
            bidding.setInteriorState(taskResult.getData().getStatus());
            bidding.setInteriorNextStep(taskResult.getData().getStep());
            //保存内部流转记录
            saveInteriorLog(sysUser, BiddingOperationStateEnum.SUBMIT_AUDIT_BIDDING.getState(), taskResult.getData().getStatus(), taskResult.getData().getStep(), bidding.getId(), "");
            //发送采购竞价消息
            purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_audit_step_1);
        }
        biddingRepository.saveAll(biddings);
        return Wrapper.success();
    }

    /**
     * 采购竞价-待审核采购竞价单列表(一级)
     */
    @Override
    public Wrapper<PageData<BiddingListResponse>> biddingStayExamineList1(BiddingListRequest request, UserLoginCacheDTO sysUser) {
        Wrapper<PageData<BiddingListResponse>> dataWrapper = getQuery(sysUser, request, BiddingListEnum.EXAMINE_PURCHASE_BIDDING_LIST1.getType());
        List<BiddingListResponse> data = dataWrapper.getData().getData();
        if (!CollectionUtils.isEmpty(data)){
            data.forEach(biddingListResponse -> biddingListResponse.setButtons(Collections.singletonList(BiddingButtonEnums.AUDIT.getState())));
        }
        return dataWrapper;
    }

    /**
     * 采购竞价-审核采购竞价单(一级)
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Wrapper<Void> biddingExamine1(BaseExamineRequest request, UserLoginCacheDTO sysUser) {
        Bidding bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //内部状态为 待审核采购竞价单(一级)
        if (!BiddingInteriorWorkStateEnum.STAY_AUDIT_BIDDING1.getState().equals(bidding.getInteriorState())) {
            return Wrapper.fail(ResponseCode.PURCHASE_NOT_AUDIT);
        }
        //执行下一步工作流
        Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), request.getId(), ProcessEnum.PURCHASE_BIDDING_INTERIOR.getCode(), bidding.getInteriorNextStep(), bidding.getInteriorTaskId(), request.getState());
        if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
            return Wrapper.fail(taskResult.getMessage());
        }
        bidding.setInteriorTaskId(taskResult.getData().getTaskId());
        bidding.setInteriorState(taskResult.getData().getStatus());
        bidding.setInteriorNextStep(taskResult.getData().getStep());
        //保存内部流转记录
        saveInteriorLog(sysUser, BiddingOperationStateEnum.AUDIT_BIDDING1.getState(), taskResult.getData().getStatus(), taskResult.getData().getStep(), bidding.getId(), OrderConstant.State.START.equals(request.getState()) ? StatusEnum.AGREE.getCHName() : request.getAuditOpinion());
        biddingRepository.saveAndFlush(bidding);

        //发送系统消息
        if (OrderConstant.State.START.equals(request.getState())) {
            purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_audit_step_2);
        } else {
            purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_wait_audit);
        }

        return Wrapper.success();
    }

    /**
     * 采购竞价-审核采购竞价单(一级)批量审核通过
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Wrapper<Void> biddingExamine1Batch(BaseAllRequest request, UserLoginCacheDTO sysUser) {
        List<Bidding> biddings = biddingRepository.findAllByCreateMemberIdAndCreateMemberRoleIdAndIdIn(sysUser.getMemberId(), sysUser.getMemberRoleId(), request.getIds());
        if (CollectionUtils.isEmpty(biddings)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        for (Bidding bidding : biddings) {
            if (ObjectUtils.isEmpty(bidding)) {
                return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
            }
            //内部状态为 待审核采购竞价单(一级)
            if (!BiddingInteriorWorkStateEnum.STAY_AUDIT_BIDDING1.getState().equals(bidding.getInteriorState())) {
                return Wrapper.fail(ResponseCode.PURCHASE_NOT_AUDIT);
            }
            //内部流程执行下一步工作流
            Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_INTERIOR.getCode(), bidding.getInteriorNextStep(), bidding.getInteriorTaskId(), OrderConstant.Auditing.PASS);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                return Wrapper.fail(taskResult.getMessage());
            }
            bidding.setInteriorTaskId(taskResult.getData().getTaskId());
            bidding.setInteriorState(taskResult.getData().getStatus());
            bidding.setInteriorNextStep(taskResult.getData().getStep());
            //保存内部流转记录
            saveInteriorLog(sysUser, BiddingOperationStateEnum.AUDIT_BIDDING1.getState(), taskResult.getData().getStatus(), taskResult.getData().getStep(), bidding.getId(), StatusEnum.AGREE.getCHName());
            purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_audit_step_2);
        }
        biddingRepository.saveAll(biddings);
        return Wrapper.success();
    }

    /**
     * 采购竞价-待审核采购竞价单(二级)
     */
    @Override
    public Wrapper<PageData<BiddingListResponse>> biddingStayExamineList2(BiddingListRequest request, UserLoginCacheDTO sysUser) {
        Wrapper<PageData<BiddingListResponse>> dataWrapper = getQuery(sysUser, request, BiddingListEnum.EXAMINE_PURCHASE_BIDDING_LIST2.getType());
        List<BiddingListResponse> data = dataWrapper.getData().getData();
        if (!CollectionUtils.isEmpty(data)){
            data.forEach(biddingListResponse -> biddingListResponse.setButtons(Collections.singletonList(BiddingButtonEnums.AUDIT.getState())));
        }
        return dataWrapper;
    }

    /**
     * 采购竞价-审核采购竞价单(二级)
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Wrapper<Void> biddingExamine2(BaseExamineRequest request, UserLoginCacheDTO sysUser) {
        Bidding bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //内部状态为 待审核采购竞价单(二级)
        if (!BiddingInteriorWorkStateEnum.STAY_SUBMIT_BIDDING2.getState().equals(bidding.getInteriorState())) {
            return Wrapper.fail(ResponseCode.PURCHASE_NOT_AUDIT);
        }
        //内部流程执行下一步工作流
        Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), request.getId(), ProcessEnum.PURCHASE_BIDDING_INTERIOR.getCode(), bidding.getInteriorNextStep(), bidding.getInteriorTaskId(), request.getState());
        if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
            return Wrapper.fail(taskResult.getMessage());
        }
        bidding.setInteriorTaskId(taskResult.getData().getTaskId());
        bidding.setInteriorState(taskResult.getData().getStatus());
        bidding.setInteriorNextStep(taskResult.getData().getStep());
        //保存内部流转记录
        saveInteriorLog(sysUser, BiddingOperationStateEnum.AUDIT_BIDDING2.getState(), taskResult.getData().getStatus(), taskResult.getData().getStep(), bidding.getId(), OrderConstant.State.START.equals(request.getState()) ? StatusEnum.AGREE.getCHName() : request.getAuditOpinion());
        biddingRepository.saveAndFlush(bidding);
        //发送系统消息
        if (OrderConstant.State.START.equals(request.getState())) {
            purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_submit);
        } else {
            purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_wait_audit);
        }
        return Wrapper.success();
    }

    /**
     * 采购竞价-审核采购竞价单(二级)批量
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Wrapper<Void> biddingExamine2Batch(BaseAllRequest request, UserLoginCacheDTO sysUser) {
        List<Bidding> biddings = biddingRepository.findAllByCreateMemberIdAndCreateMemberRoleIdAndIdIn(sysUser.getMemberId(), sysUser.getMemberRoleId(), request.getIds());
        if (CollectionUtils.isEmpty(biddings)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        for (Bidding bidding : biddings) {
            if (ObjectUtils.isEmpty(bidding)) {
                return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
            }
            //内部状态为 待审核采购竞价单(二级)
            if (!BiddingInteriorWorkStateEnum.STAY_SUBMIT_BIDDING2.getState().equals(bidding.getInteriorState())) {
                return Wrapper.fail(ResponseCode.PURCHASE_NOT_AUDIT);
            }
            //内部流程执行下一步工作流
            Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_INTERIOR.getCode(), bidding.getInteriorNextStep(), bidding.getInteriorTaskId(), OrderConstant.Auditing.PASS);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                return Wrapper.fail(taskResult.getMessage());
            }
            bidding.setInteriorTaskId(taskResult.getData().getTaskId());
            bidding.setInteriorState(taskResult.getData().getStatus());
            bidding.setInteriorNextStep(taskResult.getData().getStep());
            //保存内部流转记录
            saveInteriorLog(sysUser, BiddingOperationStateEnum.AUDIT_BIDDING2.getState(), taskResult.getData().getStatus(), taskResult.getData().getStep(), bidding.getId(), StatusEnum.AGREE.getCHName());
            //发送系统消息
            purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_submit);
        }
        biddingRepository.saveAll(biddings);
        return Wrapper.success();
    }

    /**
     * 采购竞价-待提交采购竞价单
     */
    @Override
    public Wrapper<PageData<BiddingListResponse>> biddingStaySubmitList(BiddingListRequest request, UserLoginCacheDTO sysUser) {
        Wrapper<PageData<BiddingListResponse>> dataWrapper = getQuery(sysUser, request, BiddingListEnum.SUBMIT_PURCHASE_BIDDING_LIST.getType());
        List<BiddingListResponse> data = dataWrapper.getData().getData();
        if (!CollectionUtils.isEmpty(data)){
            data.forEach(biddingListResponse -> biddingListResponse.setButtons(Collections.singletonList(BiddingButtonEnums.SUBMIT_A_PURCHASE_BID.getState())));
        }
        return dataWrapper;
    }

    /**
     * 采购竞价-提交采购竞价单
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> biddingSubmit(BaseExamineRequest request, UserLoginCacheDTO sysUser) {
        Bidding bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //内部状态为 待提交采购竞价单
        if (!BiddingInteriorWorkStateEnum.STAY_CONFIRMATION_BIDDING.getState().equals(bidding.getInteriorState())) {
            return Wrapper.fail(ResponseCode.PURCHASE_NOT_AUDIT);
        }
        //执行内部工作流
        Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), request.getId(), ProcessEnum.PURCHASE_BIDDING_INTERIOR.getCode(), bidding.getInteriorNextStep(), bidding.getInteriorTaskId(), OrderConstant.Auditing.DEFAULT);
        if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
            return Wrapper.fail(taskResult.getMessage());
        }
        //执行外部工作流
        Wrapper<SimpleTaskCompleteVO> externalTaskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), request.getId(), ProcessEnum.PURCHASE_BIDDING_EXTERNAL.getCode(), bidding.getExternalNextStep(), bidding.getExternalTaskId(), OrderConstant.Auditing.DEFAULT);
        if (ResponseCode.SUCCESS.getCode() != externalTaskResult.getCode()) {
            return Wrapper.fail(externalTaskResult.getMessage());
        }
        bidding.setInteriorTaskId(taskResult.getData().getTaskId());
        bidding.setInteriorState(taskResult.getData().getStatus());
        bidding.setInteriorNextStep(taskResult.getData().getStep());
        bidding.setExternalTaskId(externalTaskResult.getData().getTaskId());
        bidding.setExternalState(externalTaskResult.getData().getStatus());
        bidding.setExternalNextStep(externalTaskResult.getData().getStep());
        //保存内部流转记录
        saveInteriorLog(sysUser, BiddingOperationStateEnum.SUBMIT_BIDDING.getState(), taskResult.getData().getStatus(), taskResult.getData().getStep(), bidding.getId(), "");
        //保存外部流转记录
        saveExternalLog(sysUser, BiddingOperationStateEnum.SUBMIT_BIDDING.getState(), externalTaskResult.getData().getStatus(), bidding.getId(), null,"", null, null);
        //创建在线竞价单 内外部状态为待竞价报名
        OnLineBidding onlineBidding = onlineBiddinService.createOnlineBidding(bidding.getId(), bidding.getBiddingNo(), bidding.getExternalState());
        bidding.setOnLineBidding(onlineBidding);
        biddingRepository.saveAndFlush(bidding);
        //发送供应商竞价报名系统消息
        sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_wait_register);
        //同时创建MQ延时任务, 进行报名截止时间后续处理
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            //事务提交后执行创建MQ报名截止延时任务
            @Override
            public void afterCommit() {
                //发送MQ定时处理报名时间业务
                OrderRbbitMqRequest rbbitMqRequest = new OrderRbbitMqRequest();
                rbbitMqRequest.setId(bidding.getId());
                rbbitMqRequest.setMemberId(bidding.getCreateMemberId());
                rbbitMqRequest.setMemberRoleId(bidding.getCreateMemberRoleId());
                rbbitMqRequest.setExpirationTime(bidding.getEndSignUp());
                rabbitMQProvider.sendDelayMessage(rbbitMqRequest, MessageConstants.PURCHASE_BIDDING_DELAY_EXCHANGE, MessageConstants.PURCHASE_BIDDING_DELAY_KEY, -10000L);
            }
        });
        return Wrapper.success();
    }

    /**
     * 给供应商发送竞价报名消息
     */
    @Async
    public void sendSystemMessageBidding(Bidding bidding, String name) {
        try {
            SystemMessageRequest request = new SystemMessageRequest();
            request.setMemberId(bidding.getCreateMemberId());
            request.setRoleId(bidding.getCreateMemberRoleId());
            request.setMessageNotice(name);
            request.setParams(Arrays.asList(bidding.getBiddingNo(), bidding.getDetails(), BiddingOperationStateEnum.BIDDING_ONLINE.getCHName()));
            systemMessageControllerFeign.sendSystemMessage(request);
        } catch (Exception e) {
            log.error("发送竞价单通知消息异常", e);
        }
    }

    /**
     * 采购竞价-批量提交采购竞价单
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> biddingSubmitBatch(BaseAllRequest request, UserLoginCacheDTO sysUser) {
        List<Bidding> biddings = biddingRepository.findAllByCreateMemberIdAndCreateMemberRoleIdAndIdIn(sysUser.getMemberId(), sysUser.getMemberRoleId(), request.getIds());
        if (CollectionUtils.isEmpty(biddings)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        for (Bidding bidding : biddings) {
            if (ObjectUtils.isEmpty(bidding)) {
                return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
            }
            //内部状态为 待提交采购竞价单
            if (!BiddingInteriorWorkStateEnum.STAY_CONFIRMATION_BIDDING.getState().equals(bidding.getInteriorState())) {
                return Wrapper.fail(ResponseCode.PURCHASE_NOT_AUDIT);
            }
            //执行内部工作流
            Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_INTERIOR.getCode(), bidding.getInteriorNextStep(), bidding.getInteriorTaskId(), OrderConstant.Auditing.DEFAULT);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                return Wrapper.fail(taskResult.getMessage());
            }
            //执行外部工作流
            Wrapper<SimpleTaskCompleteVO> externalTaskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_EXTERNAL.getCode(), bidding.getExternalNextStep(), bidding.getExternalTaskId(), OrderConstant.Auditing.DEFAULT);
            if (ResponseCode.SUCCESS.getCode() != externalTaskResult.getCode()) {
                return Wrapper.fail(externalTaskResult.getMessage());
            }
            bidding.setInteriorTaskId(taskResult.getData().getTaskId());
            bidding.setInteriorState(taskResult.getData().getStatus());
            bidding.setInteriorNextStep(taskResult.getData().getStep());
            bidding.setExternalTaskId(externalTaskResult.getData().getTaskId());
            bidding.setExternalState(externalTaskResult.getData().getStatus());
            bidding.setExternalNextStep(externalTaskResult.getData().getStep());
            //保存内部流转记录
            saveInteriorLog(sysUser, BiddingOperationStateEnum.SUBMIT_BIDDING.getState(), taskResult.getData().getStatus(), taskResult.getData().getStep(), bidding.getId(), "");
            //保存外部流转记录
            saveExternalLog(sysUser, BiddingOperationStateEnum.SUBMIT_BIDDING.getState(), externalTaskResult.getData().getStatus(), bidding.getId(), null,"", null, null);

            //创建在线竞价单 内外部状态为待竞价报名
            OnLineBidding onlineBidding = onlineBiddinService.createOnlineBidding(bidding.getId(), bidding.getBiddingNo(), bidding.getExternalState());
            bidding.setOnLineBidding(onlineBidding);
            //同时创建MQ延时任务, 进行报名截止时间后续处理
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                //事务提交后执行创建MQ报名截止延时任务
                @Override
                public void afterCommit() {
                    //发送MQ定时处理报名时间业务
                    OrderRbbitMqRequest rbbitMqRequest = new OrderRbbitMqRequest();
                    rbbitMqRequest.setId(bidding.getId());
                    rbbitMqRequest.setMemberId(bidding.getCreateMemberId());
                    rbbitMqRequest.setMemberRoleId(bidding.getCreateMemberRoleId());
                    rbbitMqRequest.setExpirationTime(bidding.getEndSignUp());
                    rabbitMQProvider.sendDelayMessage(rbbitMqRequest, MessageConstants.PURCHASE_BIDDING_DELAY_EXCHANGE, MessageConstants.PURCHASE_BIDDING_DELAY_KEY, -10000L);
                }
            });
        }
        biddingRepository.saveAll(biddings);
        return Wrapper.success();
    }

    /**
     * 待审核竞价报名
     */
    @Override
    public Wrapper<PageData<OnlineBiddingListResponse>> stayExaminBiddingList(BiddingListRequest request, UserLoginCacheDTO sysUser) {
        return queryOnlineBiddingList(request, sysUser);
    }

    /**
     * 审核竞价报名
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Wrapper<Void> stayExaminBiddingSignup(BiddingAudteRequest request, UserLoginCacheDTO sysUser) {
        Bidding bidding = biddingRepository.findById(request.getId()).orElse(null);
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        OnLineBidding onLineBidding = onLineBiddingRepository.findFirstByBiddingId(bidding.getId());
        if (ObjectUtils.isEmpty(onLineBidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //报名信息
        OnlineMateriel onlineMateriel = onlineMaterielRepository.findByOnlineBiddingAndCreateMemberIdAndCreateMemberRoleIdAndIsSignUp(onLineBidding, request.getMemberId(), request.getMemberRoleId(), StatusEnum.YES.getState());
        if (Objects.isNull(onlineMateriel)){
            return Wrapper.fail(ResponseCode.NOT_BIDDING_REGISTRATION);
        }
        //内外部审核状态要为待审核竞价报名 且未系统自动作废
        if (!OnlineAudteInteriorStateEnum.TO_BE_SIGNUP_APPROVED_BY_BIDDING.getState().equals(onlineMateriel.getInteriorAdutState()) &&
                !OnlineAudteExternalStateEnum.STAY_EXAMINE_SIGNUP_BIDDING.getState().equals(onlineMateriel.getExternalAdutState()) &&
                !OnlineBiddingExternalWorkStateEnum.CANCEL.getState().equals(onLineBidding.getExternalState())){
            return Wrapper.fail(ResponseCode.QUOTED_PRICE_STATE_NOT);
        }
        //审核是否通过
        //内部审核状态为已审核竞价报名
        onlineMateriel.setInteriorAdutState(OnlineAudteInteriorStateEnum.BIDDING_SIGNUP_HAS_BEEN_SIGNED_UP.getState());
        if (StatusEnum.AGREE.getState().equals(request.getState())){
            //外部状态和外部审核状态为竞价报名审核通过
            onlineMateriel.setExternalAdutState(OnlineAudteExternalStateEnum.SIGNUP_BIDDING_PASS.getState());
            onlineMateriel.setExternalState(OnlineBiddingExternalWorkStateEnum.SIGNUP_BIDDING_PASS.getState());
            //
        }else {
            //外部状态和外部审核状态为竞价报名审核不通过
            onlineMateriel.setExternalAdutState(OnlineAudteExternalStateEnum.SIGNUP_BIDDING_NOT.getState());
            onlineMateriel.setExternalState(OnlineBiddingExternalWorkStateEnum.SIGNUP_BIDDING_NOT.getState());
        }
        onlineMaterielRepository.saveAndFlush(onlineMateriel);

        //内部流转记录 判断当前竞价单的所有报名会员内部状态是否是已审核竞价状态 是则记录内部状态
        List<OnlineMateriel> materiels = onLineBidding.getMateriels().stream().filter(materiel -> StatusEnum.YES.getState().equals(materiel.getIsSignUp())).collect(Collectors.toList());
        if (materiels.stream().allMatch(temp ->OnlineAudteInteriorStateEnum.BIDDING_SIGNUP_HAS_BEEN_SIGNED_UP.getState().equals(temp.getInteriorAdutState()))) {
            saveInteriorLog(sysUser, BiddingOperationStateEnum.AUDIT_BIDDING_ONLINE.getState(), BiddingInteriorWorkStateEnum.SIGNUP_EXAMIN_NOT2.getState(), null, bidding.getId(), "");
        }
        //外部流转记录
        saveExternalLog(sysUser, BiddingOperationStateEnum.AUDIT_BIDDING_ONLINE.getState(), BiddingExternalWorkStateEnum.STAY_BIDDING.getState(), bidding.getId(), ExternalLogTypeEnum.EXAMINE_REGISTRATION.getCode(), StatusEnum.AGREE.getState().equals(request.getState()) ? StatusEnum.AGREE.getCHName() : request.getAuditOpinion(), request.getMemberId(), request.getMemberRoleId());
        //待竞价系统消息
//        purchaseMessageFeign.sendSystemMessageOnLineBidding(onLineBidding, MessageTemplateCode.purchase_bidding_wait_bidding);
        return Wrapper.success();
    }

    /**
     * 待竞价
     */
    @Override
    public Wrapper<PageData<BiddingListResponse>> stayBiddingList(BiddingListRequest request, UserLoginCacheDTO sysUser) {
        Wrapper<PageData<BiddingListResponse>> dataWrapper = getQuery(sysUser, request, BiddingListEnum.STAY_BIDDING.getType());
        List<BiddingListResponse> data = dataWrapper.getData().getData();
        if (!CollectionUtils.isEmpty(data)){
            data.forEach(biddingListResponse -> {
                //需要判断竞价是否开始, 未开始则不显示竞价管理
                long time = System.currentTimeMillis();
                if (time >= biddingListResponse.getBiddingStartTime()){
                    biddingListResponse.setButtons(Collections.singletonList(BiddingButtonEnums.BID_MANAGEMENT.getState()));
                }
            });
        }
        return dataWrapper;
    }

    /**
     * 竞价管理
     */
    @Override
    public Wrapper<ManageBiddingResponse> manageBidding(BaseDetailsRequest request, UserLoginCacheDTO sysUser) {
        ManageBiddingResponse response = new ManageBiddingResponse();
        //查询竞价单
        Bidding bidding;
        if (null != request.getId()) {
            bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        } else {
            bidding = biddingRepository.findByBiddingNoAndCreateMemberIdAndCreateMemberRoleId(request.getNumber(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        }
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //查询采购竞价单外部流程状态图
        response.setExternalLogStates(getLogStateExternal(ProcessEnum.PURCHASE_BIDDING_EXTERNAL.getCode(), bidding.getExternalNextStep(),bidding.getOnLineBidding().getMemberRoleId(),bidding.getCreateMemberRoleId()));
        response.setId(bidding.getId());
        response.setDetails(bidding.getDetails());
        response.setAllowPurchaseCount(bidding.getAllowPurchaseCount());
        response.setAreas(bidding.getAreas().stream().map(temp -> BeanUtil.copyProperties(temp, CountryAreaResponse.class)).collect(Collectors.toList()));
        response.setBiddingNo(bidding.getBiddingNo());
        response.setBiddingEndTime(bidding.getBiddingEndTime());
        response.setIsTargetPrice(bidding.getIsTargetPrice());
        response.setTargetPrice(bidding.getTargetPrice());
        response.setIsStartingPrice(bidding.getIsStartingPrice());
        response.setStartingPrice(bidding.getStartingPrice());
        response.setIsMinPrice(bidding.getIsMinPrice());
        response.setMinPrice(bidding.getMinPrice());
        response.setMaterielMode(bidding.getMaterielMode());
        response.setIsOpenRanking(bidding.getIsOpenRanking());
        response.setIsOpenPurchase(bidding.getIsOpenPurchase());
        response.setIsAreas(bidding.getIsAreas());
        return Wrapper.success(response);
    }

    /**
     * 竞价动态-竞价管理
     */
    @Override
    public Wrapper<BiddingDynamicResponse> dynamicBidding(BaseDetailsRequest request, UserLoginCacheDTO sysUser) {
        BiddingDynamicResponse biddingDynamic = new BiddingDynamicResponse();
        //先从缓存查询
        Map<String, String> map = redisStringUtils.hGetAll(PurchaseInquiryConstant.BIDDING_RANKING_COUNT_KEY + request.getId(), Constants.PURCHASE_INDEX);
        //从数据库查询
        if (CollectionUtils.isEmpty(map)) {
            Bidding bidding = biddingRepository.findById(request.getId()).orElse(null);
            if (ObjectUtils.isEmpty(bidding)) {
                return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
            }
            OnLineBidding onLineBidding = onLineBiddingRepository.findFirstByBiddingId(bidding.getId());
            if (ObjectUtils.isEmpty(onLineBidding)) {
                return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
            }

            List<OnLineBiddingProduct> products = productRepository.findAllByBiddingNoOrderByReportTimeDesc(bidding.getBiddingNo());
            if (CollectionUtils.isEmpty(products)){
                return Wrapper.success(biddingDynamic);
            }
            //获取最低价竞价
            OnLineBiddingProduct product = products.get(0);
            OnlineMateriel onlineMateriel = product.getOnlineMateriel();
            map.put(PurchaseInquiryConstant.BiddingDynamic.COUNT, onLineBidding.getCount() + "");
            map.put(PurchaseInquiryConstant.BiddingDynamic.MIN_PRICE, null == onlineMateriel.getSumPrice() ? "0" : onlineMateriel.getSumPrice() + "");
            map.put(PurchaseInquiryConstant.BiddingDynamic.MEMBER_NAME, onlineMateriel.getCreateMemberName());
            //缓存竞价动态
            redisStringUtils.hMSet(PurchaseInquiryConstant.BIDDING_RANKING_COUNT_KEY + onLineBidding.getId(), map, Constants.PURCHASE_INDEX);
        }
        biddingDynamic.setId(request.getId());
        biddingDynamic.setCount(Long.valueOf(null == map.get(PurchaseInquiryConstant.BiddingDynamic.COUNT) ? "0" : map.get(PurchaseInquiryConstant.BiddingDynamic.COUNT)));
        biddingDynamic.setMemberName(map.get(PurchaseInquiryConstant.BiddingDynamic.MEMBER_NAME));
        biddingDynamic.setMinPrice(Double.valueOf(StringUtils.hasLength(map.get(PurchaseInquiryConstant.BiddingDynamic.MIN_PRICE)) ? map.get(PurchaseInquiryConstant.BiddingDynamic.MIN_PRICE) : "0"));
        return Wrapper.success(biddingDynamic);
    }

    /**
     * 竞价排名-竞价管理
     */
    @Override
    public Wrapper<List<QuotationRankingResponse>> rankingBidding(BaseDetailsRequest request, UserLoginCacheDTO sysUser) {
        return Wrapper.success(rankingBidding(request));
    }

    /**
     * 报名会员-竞价管理
     */
    @Override
    public Wrapper<List<SginUpInfoResponse>> signupMember(BaseDetailsRequest request, UserLoginCacheDTO sysUser) {
        List<SginUpInfoResponse> sginUpInfo = getSginUpInfo(request.getId());
        return Wrapper.success(sginUpInfo);
    }

    /**
     * 竞价物料&报价台-竞价管理
     */
    @Override
    public Wrapper<List<AwardProcessResponse>> biddingMateriel(BaseDetailsRequest request, UserLoginCacheDTO sysUser) {
        List<AwardProcessResponse> list = getAwardProcess(request.getId());
        //排序：正序
        if(CollectionUtil.isNotEmpty(list)){
            list = list.stream().sorted(Comparator.comparing(AwardProcessResponse::getSumPice)).collect(Collectors.toList());
        }
        return Wrapper.success(list);
    }

    /**
     * 获取采购竞价单内部流程
     */
    @Override
    public Wrapper<List<BiddingExternalWorkStateEnumResponse>> interiorStatus() {
        List<BiddingExternalWorkStateEnumResponse> collect = Arrays.stream(BiddingInteriorWorkStateEnum.values()).map(temp -> {
            BiddingExternalWorkStateEnumResponse response = new BiddingExternalWorkStateEnumResponse();
            response.setName(temp.getName());
            response.setSatatus(temp.getState());
            return response;
        }).collect(Collectors.toList());
        return Wrapper.success(collect);
    }

    /**
     * 获取采购竞价单外部部流程状态
     */
    @Override
    public Wrapper<List<BiddingExternalWorkStateEnumResponse>> externalStatus() {
        List<BiddingExternalWorkStateEnumResponse> collect = Arrays.stream(BiddingExternalWorkStateEnum.values()).map(temp -> {
            BiddingExternalWorkStateEnumResponse response = new BiddingExternalWorkStateEnumResponse();
            response.setName(temp.getName());
            response.setSatatus(temp.getState());
            return response;
        }).collect(Collectors.toList());
        return Wrapper.success(collect);
    }


    /**
     * 待提交审核竞价结果
     */
    @Override
    public Wrapper<PageData<StaySubmitBiddingListResponse>> staySubmitBiddingList(BiddingListRequest request, UserLoginCacheDTO sysUser) {
        Wrapper<PageData<StaySubmitBiddingListResponse>> pageDataWrapper = querySatySubmitBiddingList(request, BiddingListEnum.STAY_SUBMIT_EXAMINE_BIDDING_RETURN.getType());
        if (ResponseCode.SUCCESS.getCode() == pageDataWrapper.getCode() && 0 < pageDataWrapper.getData().getTotalCount()) {
            List<StaySubmitBiddingListResponse> staySubmitBiddingLists = pageDataWrapper.getData().getData();
            staySubmitBiddingLists.forEach(staySubmitBidding -> {
                staySubmitBidding.setExternalStateName(BiddingExternalWorkStateEnum.getName(staySubmitBidding.getExternalState()));
                staySubmitBidding.setInteriorStateName(BiddingReturnInteriorWorkStateEnum.getName(staySubmitBidding.getInteriorState()));
                if (BiddingInteriorWorkStateEnum.STAY_SUBMIT_BIDDING_RETUEN.getState().equals(staySubmitBidding.getInteriorState())) {
                    staySubmitBidding.setButtons(Collections.singletonList(BiddingButtonEnums.SUBMIT_FOR_REVIEW_BIDDING_RESULTS.getState()));
                } else {
                    staySubmitBidding.setButtons(Collections.singletonList(BiddingButtonEnums.EDIT_AUCTION_RESULTS.getState()));
                }
            });
        }
        return pageDataWrapper;
    }

    /**
     * 提交审核竞价结果详情
     */
    @Override
    public Wrapper<StaySubmitDetailsResponse> staySubmitDetails(BaseDetailsRequest request, UserLoginCacheDTO sysUser) {
        StaySubmitDetailsResponse response = new StaySubmitDetailsResponse();
        Bidding bidding;
        if (null != request.getId()) {
            bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        } else {
            bidding = biddingRepository.findByBiddingNoAndCreateMemberIdAndCreateMemberRoleId(request.getNumber(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        }
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        BeanUtils.copyProperties(bidding, response);
        response.setReturnUrls(bidding.getOnLineBidding().getReturnUrls());
        response.setInteriorStateName(BiddingInteriorWorkStateEnum.getName(bidding.getInteriorState()));
        response.setExternalStateName(BiddingExternalWorkStateEnum.getName(bidding.getExternalState()));
        response.setAreas(bidding.getAreas().stream().map(temp -> {
            CountryAreaResponse countryArea = new CountryAreaResponse();
            BeanUtils.copyProperties(temp, countryArea);
            return countryArea;
        }).collect(Collectors.toList()));
        Long id = bidding.getId();
        //查询采购竞价单物料信息列表
        response.setMateriels(getMateriels(id));
        //查询采购竞价结果单内部流程记录
        response.setInteriorLogs(getBiddingInteriorLog(id));
        //查询采购竞价单外部流程记录
        response.setExternalLogs(getExternalLog(id));
        //查询采购竞价单外部流程状态图
        response.setExternalLogStates(getLogStateExternal(ProcessEnum.PURCHASE_BIDDING_EXTERNAL.getCode(), bidding.getExternalNextStep(),bidding.getOnLineBidding().getMemberRoleId(),bidding.getCreateMemberRoleId()));
        //审核竞价结果内部流转状态图
        response.setExamineInteriorLogStates(getLogStateInterior(ProcessEnum.PURCHASE_BIDDING_EXAMINE_INTERIOR.getCode(), bidding.getAuditInteriorNextStep()));
        //查询报名信息
        response.setSginUpInfos(getSginUpInfo(id));
        //授标结果
        response.setAwardsFruit(getAwardsFruits(id));
        //查看竞价过程
        response.setAwardProcess(getAwardProcess(id));

        purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_result_audit_step_1);
        return Wrapper.success(response);
    }

    /**
     * 提交审核竞价结果
     */
    @Transactional
    @Override
    public Wrapper<Void> submitExamineBiddingReturn(SubmitExamineBiddingReturnRequest request, UserLoginCacheDTO sysUser) {
        Bidding bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getBiddingId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //授标结果
        AwardsFruitsResponse awardsFruit = getAwardsFruits(bidding.getId());
        //是否有供应商被授标
        if (getPrize(awardsFruit)){
            return Wrapper.fail(ResponseCode.PLEASE_CHOICE_PRIZE_ORDER);
        }
        OnLineBidding onLineBidding = onLineBiddingRepository.findFirstByBiddingId(request.getBiddingId());
        if (Objects.isNull(onLineBidding)) {
            return Wrapper.fail(ResponseCode.PLEASE_CHOICE_PRIZE_ORDER);
        }
        //内部审核状态为待提交审核结果
        Integer auditInteriorState = bidding.getAuditInteriorState();
        if (!BiddingInteriorWorkStateEnum.STAY_SUBMIT_BIDDING_RETUEN.getState().equals(auditInteriorState)){
            return Wrapper.fail(ResponseCode.BIDDING_DOCUMENTS_CANNOT_BE_APPROVED);
        }
        //记录中标信息
        onLineBidding.setReturnUrls(request.getUrls());
        onLineBidding.setSignUpIdea(request.getSignUpIdea());
        onLineBiddingRepository.saveAndFlush(onLineBidding);

        //执行内部工作流
        Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_EXAMINE_INTERIOR.getCode(), bidding.getAuditInteriorNextStep(), bidding.getAuditInteriorTaskId(), OrderConstant.Auditing.DEFAULT);
        if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
            throw new RuntimeException(taskResult.getMessage());
        }
        bidding.setAuditInteriorTaskId(taskResult.getData().getTaskId());
        bidding.setAuditInteriorState(taskResult.getData().getStatus());
        bidding.setAuditInteriorNextStep(taskResult.getData().getStep());
        bidding.setInteriorState(taskResult.getData().getStatus());
        //内部记录流转
        saveInteriorLog(sysUser, BiddingOperationStateEnum.SUBMIT_BIDDING_RESULT.getState(), taskResult.getData().getStatus(), taskResult.getData().getStatus(), bidding.getId(), "");
        biddingRepository.saveAndFlush(bidding);
        //发送系统消息
        purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_result_audit_step_1);
        return Wrapper.success();
    }

    /**
     * 修改审核竞价结果
     */
    @Transactional
    @Override
    public Wrapper<Void> updateBiddingReturn(SubmitExamineBiddingReturnRequest request, UserLoginCacheDTO sysUser) {
        Bidding bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getBiddingId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        AwardsFruitsResponse awardsFruit = getAwardsFruits(bidding.getId());
        //是否有供应商被授标
        if (getPrize(awardsFruit)){
            return Wrapper.fail(ResponseCode.PLEASE_CHOICE_PRIZE_ORDER);
        }
        OnLineBidding onLineBidding = onLineBiddingRepository.findFirstByBiddingId(request.getBiddingId());
        if (Objects.isNull(onLineBidding)) {
            return Wrapper.fail(ResponseCode.PLEASE_CHOICE_PRIZE_ORDER);
        }
        //内部审核状态为竞价结果审核不通过(一级)、竞价结果审核不通过(二级)
        Integer auditInteriorState = bidding.getAuditInteriorState();
        if (!BiddingInteriorWorkStateEnum.AUDIT_NOT_BIDDING1_RETUEN.getState().equals(auditInteriorState) && !BiddingInteriorWorkStateEnum.AUDIT_NOT_BIDDING2_RETUEN.getState().equals(auditInteriorState)){
            return Wrapper.fail(ResponseCode.BIDDING_DOCUMENTS_CANNOT_BE_APPROVED);
        }

        long time = System.currentTimeMillis();
        //记录中标信息
        onLineBidding.setReturnUrls(request.getUrls());
        onLineBidding.setSignUpIdea(request.getSignUpIdea());
        onLineBidding.setUpdateTime(time);
        onLineBiddingRepository.saveAndFlush(onLineBidding);
        //执行内部工作流
        Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_EXAMINE_INTERIOR.getCode(), bidding.getAuditInteriorNextStep(), bidding.getAuditInteriorTaskId(), OrderConstant.Auditing.DEFAULT);
        if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
            throw new RuntimeException(taskResult.getMessage());
        }
        bidding.setAuditInteriorTaskId(taskResult.getData().getTaskId());
        bidding.setAuditInteriorState(taskResult.getData().getStatus());
        bidding.setAuditInteriorNextStep(taskResult.getData().getStep());
        bidding.setInteriorState(taskResult.getData().getStatus());
        bidding.setUpdateTime(time);
        biddingRepository.saveAndFlush(bidding);
        return Wrapper.success();
    }

    /**
     * 待审核竞价结果（一级）
     */
    @Override
    public Wrapper<PageData<StaySubmitBiddingListResponse>> staySubmitBiddingList1(BiddingListRequest request, UserLoginCacheDTO sysUser) {
        Wrapper<PageData<StaySubmitBiddingListResponse>> pageDataWrapper = querySatySubmitBiddingList(request, BiddingListEnum.STAY_SUBMIT_EXAMINE_BIDDING_RETURN1.getType());
        if (ResponseCode.SUCCESS.getCode() == pageDataWrapper.getCode() && 0 < pageDataWrapper.getData().getTotalCount()) {
            List<StaySubmitBiddingListResponse> staySubmitBiddingLists = pageDataWrapper.getData().getData();
            staySubmitBiddingLists.forEach(staySubmitBidding -> {
                staySubmitBidding.setExternalStateName(BiddingExternalWorkStateEnum.getName(staySubmitBidding.getExternalState()));
                staySubmitBidding.setInteriorStateName(BiddingReturnInteriorWorkStateEnum.getName(staySubmitBidding.getInteriorState()));
                staySubmitBidding.setButtons(Collections.singletonList(BiddingButtonEnums.REVIEW_AUCTION_RESULTS.getState()));
            });
        }
        return pageDataWrapper;

    }

    /**
     * 审核竞价结果（一级）
     */
    @Transactional
    @Override
    public Wrapper<Void> staySubmitBidding(BaseExamineRequest request, UserLoginCacheDTO sysUser) {
        Bidding bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //内部审核状态为待审核竞价结果(一级)
        Integer auditInteriorState = bidding.getAuditInteriorState();
        if (!BiddingInteriorWorkStateEnum.STAY_AUDIT_BIDDING1_RETUEN.getState().equals(auditInteriorState)){
            return Wrapper.fail(ResponseCode.BIDDING_DOCUMENTS_CANNOT_BE_APPROVED);
        }
        //执行内部工作流
        Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_EXAMINE_INTERIOR.getCode(), bidding.getAuditInteriorNextStep(), bidding.getAuditInteriorTaskId(), request.getState());
        if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
            throw new RuntimeException(taskResult.getMessage());
        }
        bidding.setAuditInteriorTaskId(taskResult.getData().getTaskId());
        bidding.setAuditInteriorState(taskResult.getData().getStatus());
        bidding.setAuditInteriorNextStep(taskResult.getData().getStep());
        bidding.setInteriorState(taskResult.getData().getStatus());
        bidding.setUpdateTime(System.currentTimeMillis());
        saveInteriorLog(sysUser, BiddingOperationStateEnum.AUDIT_BIDDING_RESULT1.getState(), taskResult.getData().getStatus(), taskResult.getData().getStep(), bidding.getId(), OrderConstant.State.START.equals(request.getState()) ? StatusEnum.AGREE.getCHName() : request.getAuditOpinion());
        biddingRepository.saveAndFlush(bidding);
        purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_result_audit_step_2);

        return Wrapper.success();
    }

    /**
     * 审核竞价结果（一级）批量
     */
    @Override
    public Wrapper<Void> staySubmitBidding1Batch(BaseAllRequest request, UserLoginCacheDTO sysUser) {
        List<Bidding> biddings = biddingRepository.findAllByCreateMemberIdAndCreateMemberRoleIdAndIdIn(sysUser.getMemberId(), sysUser.getMemberRoleId(), request.getIds());
        if (CollectionUtils.isEmpty(biddings)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        long time = System.currentTimeMillis();
        for (Bidding bidding : biddings) {
            if (ObjectUtils.isEmpty(bidding)) {
                return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
            }
            //内部审核状态为待审核竞价结果(一级)
            Integer auditInteriorState = bidding.getAuditInteriorState();
            if (!BiddingInteriorWorkStateEnum.STAY_AUDIT_BIDDING1_RETUEN.getState().equals(auditInteriorState)){
                return Wrapper.fail(ResponseCode.BIDDING_DOCUMENTS_CANNOT_BE_APPROVED);
            }
            //执行内部工作流
            Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_EXAMINE_INTERIOR.getCode(), bidding.getAuditInteriorNextStep(), bidding.getAuditInteriorTaskId(), OrderConstant.Auditing.PASS);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                throw new RuntimeException(taskResult.getMessage());
            }
            bidding.setAuditInteriorTaskId(taskResult.getData().getTaskId());
            bidding.setAuditInteriorState(taskResult.getData().getStatus());
            bidding.setAuditInteriorNextStep(taskResult.getData().getStep());
            bidding.setInteriorState(taskResult.getData().getStatus());
            bidding.setUpdateTime(time);
            saveInteriorLog(sysUser, BiddingOperationStateEnum.AUDIT_BIDDING_RESULT1.getState(), taskResult.getData().getStatus(), taskResult.getData().getStatus(), bidding.getId(), StatusEnum.AGREE.getCHName());

            purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_result_audit_step_2);
        }
        biddingRepository.saveAll(biddings);
        biddingRepository.flush();
        return Wrapper.success();
    }

    /**
     * 待审核竞价结果（二级）
     */
    @Override
    public Wrapper<PageData<StaySubmitBiddingListResponse>> staySubmitBiddingList2(BiddingListRequest request, UserLoginCacheDTO sysUser) {
        Wrapper<PageData<StaySubmitBiddingListResponse>> pageDataWrapper = querySatySubmitBiddingList(request, BiddingListEnum.STAY_SUBMIT_EXAMINE_BIDDING_RETURN2.getType());
        if (ResponseCode.SUCCESS.getCode() == pageDataWrapper.getCode() && 0 < pageDataWrapper.getData().getTotalCount()) {
            List<StaySubmitBiddingListResponse> staySubmitBiddingLists = pageDataWrapper.getData().getData();
            staySubmitBiddingLists.forEach(staySubmitBidding -> {
                staySubmitBidding.setExternalStateName(BiddingExternalWorkStateEnum.getName(staySubmitBidding.getExternalState()));
                staySubmitBidding.setInteriorStateName(BiddingReturnInteriorWorkStateEnum.getName(staySubmitBidding.getInteriorState()));
                staySubmitBidding.setButtons(Collections.singletonList(BiddingButtonEnums.REVIEW_AUCTION_RESULTS.getState()));
            });
        }
        return pageDataWrapper;
    }

    /**
     * 审核竞价结果（二级）
     */
    @Override
    public Wrapper<Void> staySubmitBidding2(BaseExamineRequest request, UserLoginCacheDTO sysUser) {
        Bidding bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //内部审核状态为待审核竞价结果(二级)
        Integer auditInteriorState = bidding.getAuditInteriorState();
        if (!BiddingInteriorWorkStateEnum.STAY_SUBMIT_BIDDING2_RETUEN.getState().equals(auditInteriorState)){
            return Wrapper.fail(ResponseCode.BIDDING_DOCUMENTS_CANNOT_BE_APPROVED);
        }
        //执行内部工作流
        Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_EXAMINE_INTERIOR.getCode(), bidding.getAuditInteriorNextStep(), bidding.getAuditInteriorTaskId(), request.getState());
        if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
            throw new RuntimeException(taskResult.getMessage());
        }
        bidding.setAuditInteriorTaskId(taskResult.getData().getTaskId());
        bidding.setAuditInteriorState(taskResult.getData().getStatus());
        bidding.setAuditInteriorNextStep(taskResult.getData().getStep());
        bidding.setInteriorState(taskResult.getData().getStatus());
        bidding.setUpdateTime(System.currentTimeMillis());
        saveInteriorLog(sysUser, BiddingOperationStateEnum.AUDIT_BIDDING_RESULT2.getState(), taskResult.getData().getStatus(), taskResult.getData().getStep(), bidding.getId(), OrderConstant.State.START.equals(request.getState()) ? StatusEnum.AGREE.getCHName() : request.getAuditOpinion());
        biddingRepository.saveAndFlush(bidding);

        if (OrderConstant.State.START.equals(request.getState())) {
            purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_result_submit);
        } else {
            purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_result_wait_audit);
        }
        return Wrapper.success();
    }

    /**
     * 审核竞价结果（二级）批量
     */
    @Override
    public Wrapper<Void> staySubmitBidding2Batch(BaseAllRequest request, UserLoginCacheDTO sysUser) {
        List<Bidding> biddings = biddingRepository.findAllByCreateMemberIdAndCreateMemberRoleIdAndIdIn(sysUser.getMemberId(), sysUser.getMemberRoleId(), request.getIds());
        if (CollectionUtils.isEmpty(biddings)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        long time = System.currentTimeMillis();
        for (Bidding bidding : biddings) {
            if (ObjectUtils.isEmpty(bidding)) {
                return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
            }
            //内部审核状态为待审核竞价结果(二级)
            Integer auditInteriorState = bidding.getAuditInteriorState();
            if (!BiddingInteriorWorkStateEnum.STAY_SUBMIT_BIDDING2_RETUEN.getState().equals(auditInteriorState)){
                return Wrapper.fail(ResponseCode.BIDDING_DOCUMENTS_CANNOT_BE_APPROVED);
            }
            //执行内部工作流
            Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_EXAMINE_INTERIOR.getCode(), bidding.getAuditInteriorNextStep(), bidding.getAuditInteriorTaskId(), OrderConstant.Auditing.PASS);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                throw new RuntimeException(taskResult.getMessage());
            }
            bidding.setAuditInteriorTaskId(taskResult.getData().getTaskId());
            bidding.setAuditInteriorState(taskResult.getData().getStatus());
            bidding.setAuditInteriorNextStep(taskResult.getData().getStep());
            bidding.setInteriorState(taskResult.getData().getStatus());
            bidding.setUpdateTime(time);
            saveInteriorLog(sysUser, BiddingOperationStateEnum.AUDIT_BIDDING_RESULT2.getState(), taskResult.getData().getStatus(), taskResult.getData().getStatus(), bidding.getId(), StatusEnum.AGREE.getCHName());

            purchaseMessageFeign.sendSystemMessageBidding(bidding, MessageTemplateCode.purchase_bidding_result_submit);
        }
        biddingRepository.saveAll(biddings);
        biddingRepository.flush();
        return Wrapper.success();
    }

    /**
     * 待确认竞价结果
     */
    @Override
    public Wrapper<PageData<StaySubmitBiddingListResponse>> stayConfirmBiddingList(BiddingListRequest request, UserLoginCacheDTO sysUser) {
        Wrapper<PageData<StaySubmitBiddingListResponse>> pageDataWrapper = querySatySubmitBiddingList(request, BiddingListEnum.STAY_COMMIT_BIDDING_RETURN.getType());
        if (ResponseCode.SUCCESS.getCode() == pageDataWrapper.getCode() && 0 < pageDataWrapper.getData().getTotalCount()) {
            List<StaySubmitBiddingListResponse> staySubmitBiddingLists = pageDataWrapper.getData().getData();
            staySubmitBiddingLists.forEach(staySubmitBidding -> {
                staySubmitBidding.setExternalStateName(BiddingExternalWorkStateEnum.getName(staySubmitBidding.getExternalState()));
                staySubmitBidding.setInteriorStateName(BiddingReturnInteriorWorkStateEnum.getName(staySubmitBidding.getInteriorState()));
                staySubmitBidding.setButtons(Collections.singletonList(BiddingButtonEnums.CONFIRM__AUCTION_RESULTS.getState()));
            });
        }
        return pageDataWrapper;
    }

    /**
     * 确认竞价结果
     */
    @Transactional
    @Override
    public Wrapper<Void> stayConfirmBidding(BaseExamineRequest request, UserLoginCacheDTO sysUser) {
        Bidding bidding = biddingRepository.findByIdAndCreateMemberIdAndCreateMemberRoleId(request.getId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        OnLineBidding onLineBidding = onLineBiddingRepository.findFirstByBiddingId(bidding.getId());
        if (ObjectUtils.isEmpty(onLineBidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //内部审核状态为待确认竞价结果
        Integer auditInteriorState = bidding.getAuditInteriorState();
        if (!BiddingInteriorWorkStateEnum.STAY_CONFIRMATION_BIDDING_RETUEN.getState().equals(auditInteriorState)){
            return Wrapper.fail(ResponseCode.BIDDING_DOCUMENTS_CANNOT_BE_APPROVED);
        }
        //执行内部工作流
        Wrapper<SimpleTaskCompleteVO> taskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_EXAMINE_INTERIOR.getCode(), bidding.getAuditInteriorNextStep(), bidding.getAuditInteriorTaskId(), request.getState());
        if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
            throw new RuntimeException(taskResult.getMessage());
        }
        bidding.setAuditInteriorTaskId(taskResult.getData().getTaskId());
        bidding.setAuditInteriorState(taskResult.getData().getStatus());
        bidding.setAuditInteriorNextStep(taskResult.getData().getStep());
        bidding.setInteriorState(taskResult.getData().getStatus());
        onLineBidding.setPrizeNotice(request.getPrizeNotice());
        onLineBidding.setThank(request.getThank());
        onLineBidding.setNotice(request.getNotice());
        onLineBidding.setAwardResults(request.getAwardResults());
        onLineBidding.setContent(request.getContent());
        //内部流转记录
        saveInteriorLog(sysUser, BiddingOperationStateEnum.CONFIRM_BIDDING_RESULT.getState(), taskResult.getData().getStatus(), taskResult.getData().getStatus(), bidding.getId(), "");
        //执行外部工作流
        Wrapper<SimpleTaskCompleteVO> externalTaskResult = executeWork(sysUser.getMemberId(), sysUser.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_EXTERNAL.getCode(), bidding.getExternalNextStep(), bidding.getExternalTaskId(), OrderConstant.Auditing.DEFAULT);
        if (ResponseCode.SUCCESS.getCode() != externalTaskResult.getCode()) {
            return Wrapper.fail(externalTaskResult.getMessage());
        }
        bidding.setExternalTaskId(externalTaskResult.getData().getTaskId());
        bidding.setExternalState(externalTaskResult.getData().getStatus());
        bidding.setExternalNextStep(externalTaskResult.getData().getStep());
        onLineBidding.setExternalState(externalTaskResult.getData().getStatus());
        //设置所有竞价供应商竞价内外部状态
        savaCompleteStatus(onLineBidding);
        //外部流转记录
        saveExternalLog(sysUser, BiddingOperationStateEnum.CONFIRM_BIDDING_RESULT.getState(), externalTaskResult.getData().getStatus(), bidding.getId(), null, "", null, null);
        biddingRepository.saveAndFlush(bidding);
        executor.execute(()->{
            List<PurchaseViePriceAddVO> addVOList =new ArrayList<>();
            PurchaseViePriceAddVO purchaseViePriceAddVO=new PurchaseViePriceAddVO();
            purchaseViePriceAddVO.setAwardAmount(onLineBidding.getSumAwardPrice());
            purchaseViePriceAddVO.setAwardMemberId(onLineBidding.getMemberId());
            purchaseViePriceAddVO.setAwardRoleId(onLineBidding.getMemberRoleId());
            purchaseViePriceAddVO.setAwardName(onLineBidding.getMemberName());
            purchaseViePriceAddVO.setAwardTime(bidding.getUpdateTime());
            purchaseViePriceAddVO.setId(onLineBidding.getId());
            purchaseViePriceAddVO.setViePriceNO(bidding.getBiddingNo());
            purchaseViePriceAddVO.setViePriceId(bidding.getId());
            purchaseViePriceAddVO.setMemberId(bidding.getCreateMemberId());
            purchaseViePriceAddVO.setRoleId(bidding.getCreateMemberRoleId());
            purchaseViePriceAddVO.setViePriceAbstract(bidding.getDetails());
            purchaseViePriceAddVO.setInnerStatus(bidding.getInteriorState());
            purchaseViePriceAddVO.setOuterStatus(bidding.getInteriorState());
            purchaseViePriceAddVO.setPublishTime(bidding.getCreateTime());
            addVOList.add(purchaseViePriceAddVO);
            purchaseViePriceControllerFeign.addList(addVOList);
        });
        //中标公示(企业门户用到)
        if (OrderConstant.State.START.equals(request.getNotice())) {
            PurchaseNotice purchaseNotice = new PurchaseNotice();
            purchaseNotice.setMemberId(sysUser.getMemberId());
            purchaseNotice.setRoleId(sysUser.getMemberRoleId());
            purchaseNotice.setType(PurchaseNoticeTypeEnum.ENQUIRY.getCode());
            purchaseNotice.setName(bidding.getDetails());
            purchaseNotice.setCreateTime(System.currentTimeMillis());
            purchaseNotice.setContent(request.getAwardResults());
            purchaseNotice.setMemberIds(
                    onLineBidding.getMateriels().stream().filter(a ->
                            EnableDisableStatus.ENABLE.getCode().equals(a.getIsPrize())
                    ).map(OnlineMateriel::getCreateMemberId).collect(Collectors.toList())
            );
            purchaseNotice.setDataId(bidding.getId());
            purchaseNotice.setShopIds(bidding.getShopIds());
            purchaseNoticeRepository.saveAndFlush(purchaseNotice);
        }
        return Wrapper.success();
    }

    /**
     * 批量设置所有供应商内外部状态为已完成
     * @param onLineBidding 在线竞价单
     */
    private void savaCompleteStatus(OnLineBidding onLineBidding) {
        //所有报名的供应商会员
        List<OnlineMateriel> materiels = onlineMaterielRepository.findAllByOnlineBiddingIdAndIsSignUp(onLineBidding.getId(), StatusEnum.YES.getState());
        if (CollectionUtils.isEmpty(materiels)) {
            return;
        }
        materiels.forEach(onlineMateriel -> {
            onlineMateriel.setExternalState(OnlineBiddingExternalWorkStateEnum.COMPLETE.getState());
            onlineMateriel.setInteriorState(OnlineInteriorWorkStateEnum.COMPLETE.getState());
        });
        onlineMaterielRepository.saveAll(materiels);
    }

    /**
     * 批量设置所有供应商内外部状态为已作废
     * @param onLineBidding 在线竞价单
     */
    private void savaCancelStatus(OnLineBidding onLineBidding) {
        List<OnlineMateriel> materiels = onlineMaterielRepository.findAllByOnlineBiddingId(onLineBidding.getId());
        if (CollectionUtils.isEmpty(materiels)){
            return;
        }
        materiels.forEach(onlineMateriel -> {
            onlineMateriel.setExternalState(OnlineBiddingExternalWorkStateEnum.CANCEL.getState());
            onlineMateriel.setInteriorState(OnlineInteriorWorkStateEnum.CANCEL.getState());
        });
        onlineMaterielRepository.saveAll(materiels);
    }


    /**
     * 查询待提交审核竞价单结果列表根据查询类型查询
     */
    private Wrapper<PageData<StaySubmitBiddingListResponse>> querySatySubmitBiddingList(BiddingListRequest request, Integer queryType) {
        List<StaySubmitBiddingListResponse> responses;
        QBidding qBidding = QBidding.bidding;
        QOnLineBidding qOnLineBidding = QOnLineBidding.onLineBidding;
        // 定于获取条件
        BooleanBuilder predicates = new BooleanBuilder();
        // predicates.and(qBidding.onlineBiddingId.eq(qOnLineBidding.id));
        if (null != request.getStartTime()) {
            predicates.and(qBidding.biddingStartTime.goe(request.getStartTime()));
        }
        if (null != request.getEndTime()) {
            predicates.and(qBidding.biddingEndTime.loe(request.getEndTime()));
        }
        if (StringUtils.hasLength(request.getDetails())) {
            predicates.and(qBidding.details.like("%" + request.getDetails() + "%"));
        }
        if (StringUtils.hasLength(request.getBiddingNo())) {
            predicates.and(qBidding.biddingNo.like("%" + request.getBiddingNo() + "%"));
        }
        predicates.and(qBidding.externalState.eq(BiddingExternalWorkStateEnum.AUDIT_DETERMINE_BIDDING.getState()));
        if (BiddingListEnum.STAY_SUBMIT_EXAMINE_BIDDING_RETURN.getType().equals(queryType)) {
            predicates.and(qBidding.auditInteriorState.in(BiddingReturnInteriorWorkStateEnum.AUDIT_NOT_BIDDING1.getState(), BiddingReturnInteriorWorkStateEnum.AUDIT_NOT_BIDDING2.getState(), BiddingReturnInteriorWorkStateEnum.STAY_SUBMIT_BIDDING.getState()));
        } else if (BiddingListEnum.STAY_SUBMIT_EXAMINE_BIDDING_RETURN1.getType().equals(queryType)) {
            predicates.and(qBidding.auditInteriorState.eq(BiddingReturnInteriorWorkStateEnum.STAY_AUDIT_BIDDING1.getState()));
        } else if (BiddingListEnum.STAY_SUBMIT_EXAMINE_BIDDING_RETURN2.getType().equals(queryType)) {
            predicates.and(qBidding.auditInteriorState.eq(BiddingReturnInteriorWorkStateEnum.STAY_SUBMIT_BIDDING2.getState()));
        } else if (BiddingListEnum.STAY_COMMIT_BIDDING_RETURN.getType().equals(queryType)) {
            predicates.and(qBidding.auditInteriorState.eq(BiddingReturnInteriorWorkStateEnum.STAY_CONFIRMATION_BIDDING.getState()));
        }
        JPAQuery<StaySubmitBiddingListResponse> query = queryFactory.select(Projections.bean(StaySubmitBiddingListResponse.class,
                qBidding.id,
                qBidding.biddingNo,
                qBidding.details,
                qBidding.createTime,
                qBidding.biddingStartTime,
                qBidding.biddingEndTime,
                qBidding.externalState,
                qBidding.auditInteriorState.as("interiorState"),
                qBidding.createMemberName.as("purchaseMemberName"),
                qOnLineBidding.memberId,
                qOnLineBidding.memberName,
                qOnLineBidding.memberRoleId,
                qOnLineBidding.sumAwardPrice.as("sumAwardPrice")))
                .from(qBidding)
                .where(predicates);
        long totalCount = query.fetchCount();
        if (queryType.equals(BiddingListEnum.STAY_SUBMIT_EXAMINE_BIDDING_RETURN.getType())){
            query.orderBy(qBidding.biddingEndTime.desc());
        }else {
            query.orderBy(qBidding.createTime.desc());
        }
        responses = query.offset(request.getCurrent() * request.getPageSize())
                .limit(request.getPageSize())
                .fetch();
        return Wrapper.success(new PageData<>(totalCount, responses));
    }


    /**
     * 清除采购竞价单中间表数据
     */
    public void clearBidding(Bidding bidding) {
        //适用地市
        List<BiddingArea> areas = bidding.getAreas();
        if (!CollectionUtils.isEmpty(areas)) {
            biddingAreaRepository.deleteAll(areas);
        }
        //物料信息
        List<BiddingProduct> products = bidding.getProducts();
        if (!CollectionUtils.isEmpty(products)) {
            biddingProductRepository.deleteAll(products);
        }
        //邀请会员
        List<BiddingDemandMember> members = bidding.getMembers();
        if (!CollectionUtils.isEmpty(members)) {
            biddingDemandMemberRepository.deleteAll(members);
        }
    }

    /**
     * 判断竞价单状态是否可以修改 true:可以修改 false：不可以修改
     */
    private boolean isUpdate(Bidding bidding) {
        //内部状态 采购竞价单审核不通过1/2级、待提交审核状态
        //外部状态 待提交采购竞价单
        return BiddingInteriorWorkStateEnum.AUDIT_NOT_BIDDING1.getState().equals(bidding.getInteriorState()) ||
                BiddingInteriorWorkStateEnum.AUDIT_NOT_BIDDING2.getState().equals(bidding.getInteriorState()) ||
                BiddingInteriorWorkStateEnum.STAY_SUBMIT_BIDDING.getState().equals(bidding.getInteriorState()) ||
                BiddingExternalWorkStateEnum.STAY_SUBMIT_BIDDING.getState().equals(bidding.getExternalState());
    }

    /**
     * 判断采购竞价单状态是否可以删除 true:可以 false：不可以
     */
    private boolean isDelete(Bidding bidding) {
        //内部状态为 待提交审核采购竞价单且从未提交过审核的采购竞价单可以删除
        return !BiddingInteriorWorkStateEnum.STAY_SUBMIT_BIDDING.getState().equals(bidding.getInteriorState()) ||
                !judgeInteriorLog(bidding.getId());
    }


    /**
     * 待审核竞价报名列表
     */
    private Wrapper<PageData<OnlineBiddingListResponse>> queryOnlineBiddingList(BiddingListRequest request, UserLoginCacheDTO sysUser) {
        List<OnlineBiddingListResponse> responses;
        QBidding qBidding = QBidding.bidding;
        QOnLineBidding qOnLineBidding = QOnLineBidding.onLineBidding;
        QOnlineMateriel qOnlineMateriel = QOnlineMateriel.onlineMateriel;
        // 定于获取条件
        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(qBidding.createMemberId.eq(sysUser.getMemberId()))
                .and(qBidding.createMemberRoleId.eq(sysUser.getMemberRoleId()))
                .and(qBidding.externalState.ne(BiddingExternalWorkStateEnum.CANCEL.getState()))
                .and(qOnlineMateriel.interiorAdutState.in(OnlineAudteInteriorStateEnum.getCodes()))
                .and(qOnlineMateriel.externalAdutState.in(OnlineAudteExternalStateEnum.getCodes()));
        //采购商名称
        if (StringUtils.hasLength(request.getMemberName())) {
            predicates.and(qBidding.createMemberName.like("%" + request.getMemberName() + "%"));
        }
        //单据创建时间
        if (null != request.getStartTime()) {
            predicates.and(qBidding.createTime.goe(request.getStartTime()));
        }
        if (null != request.getEndTime()) {
            predicates.and(qBidding.createTime.loe(request.getEndTime()));
        }
        //报名时间
        if (null != request.getSignupStartTime()) {
            predicates.and(qBidding.startSignUp.goe(request.getSignupStartTime()));
        }
        if (null != request.getSignupEndTime()) {
            predicates.and(qBidding.endSignUp.loe(request.getSignupEndTime()));
        }
        //摘要
        if (StringUtils.hasLength(request.getDetails())) {
            predicates.and(qBidding.details.like("%" + request.getDetails() + "%"));
        }
        //单号
        if (StringUtils.hasLength(request.getBiddingNo())) {
            predicates.and(qBidding.biddingNo.like("%" + request.getBiddingNo() + "%"));
        }
        JPAQuery<OnlineBiddingListResponse> query = queryFactory.select(Projections.bean(OnlineBiddingListResponse.class,
                qOnLineBidding.id,
                qBidding.id.as("biddingId"),
                qBidding.biddingNo,
                qBidding.details,
                qBidding.createTime,
                qBidding.startSignUp,
                qBidding.endSignUp,
                qOnlineMateriel.interiorAdutState.as("interiorState"),
                qOnlineMateriel.externalAdutState.as("externalState"),
                qOnlineMateriel.createMemberId,
                qOnlineMateriel.createMemberName,
                qOnlineMateriel.createMemberRoleId,
                qOnlineMateriel.signUpTime))
                .from(qBidding);
        query.leftJoin(qOnLineBidding).on(qBidding.id.eq(qOnLineBidding.bidding.id)).where(predicates);
        query.leftJoin(qOnlineMateriel).on(qOnLineBidding.id.eq(qOnlineMateriel.onlineBidding.id)).where(predicates);
        responses = query.orderBy(qOnlineMateriel.signUpTime.desc())
                .offset(request.getCurrent() * request.getPageSize())
                .limit(request.getPageSize())
                .fetch();
        responses = responses.stream().filter(response -> response.getExternalState() != null && response.getInteriorState() != null).peek(response -> {
            response.setExternalStateName(OnlineAudteExternalStateEnum.getName(response.getExternalState()));
            response.setInteriorStateName(OnlineAudteInteriorStateEnum.getName(response.getInteriorState()));
            //显示按钮
            //内部状态为待审核竞价报名的显示审核按钮
            if (OnlineAudteInteriorStateEnum.TO_BE_SIGNUP_APPROVED_BY_BIDDING.getState().equals(response.getInteriorState())){
                response.setButtons(Collections.singletonList(BiddingButtonEnums.AUDIT.getState()));
            }
        }).collect(Collectors.toList());
        return Wrapper.success(new PageData<>(query.fetchCount(), responses));
    }


    /**
     * 判断是否有人中标
     */
    private Boolean getPrize(AwardsFruitsResponse awardsFruit) {
        return awardsFruit.getMemers().stream().allMatch(memberResponse -> OrderConstant.State.STOP.equals(memberResponse.getIsAward()));
    }


    /**
     * MQ延时任务- 竞价报名结束
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void examine(OrderRbbitMqRequest request, Message message, Channel channel) {
        long millis = System.currentTimeMillis();
        //竞价单
        Bidding bidding = biddingRepository.findById(request.getId()).orElse(null);
        if (ObjectUtils.isEmpty(bidding)) {
            log.error("未找到竞价单信息, 单号:{}", request.getId());
            return;
        }
        //报价单
        OnLineBidding onLineBidding = onLineBiddingRepository.findFirstByBiddingId(bidding.getId());
        if (ObjectUtils.isEmpty(onLineBidding)) {
            log.error("未找到在线竞价单信息, 单号:{}", request.getId());
            return;
        }
        //是否已作废
        if (BiddingExternalWorkStateEnum.CANCEL.getState().equals(bidding.getExternalState()) || BiddingExternalWorkStateEnum.CANCEL.getState().equals(onLineBidding.getExternalState())){
            log.error("竞价单已作废, 单号:{}", request.getId());
            return;
        }
        if (!BiddingExternalWorkStateEnum.STAY_BIDDING_SINGNUP.getState().equals(bidding.getExternalState())){
            log.error("竞价单外部状态不是待竞价报名, 单号:{}", request.getId());
            return;
        }
        //判断单据状态是否可以执行与到期时间是否大于当前时间
        if (millis < bidding.getEndSignUp()) {
            throw new RuntimeException(ResponseCode.BIDDING_REGISTRATION_RE_CONSUMPTION.getMessage());
        }
        //作废竞价单
        //1.判断是否有人报名 无人报名的话 自动作废该竞价单
        List<OnlineMateriel> materiels = onlineMaterielRepository.findAllByOnlineBiddingIdAndIsSignUp(onLineBidding.getId(), StatusEnum.YES.getState());
        //2.判断所有报名采购商是否都为已审核
        boolean a = materiels.stream().anyMatch(member -> OnlineAudteInteriorStateEnum.TO_BE_SIGNUP_APPROVED_BY_BIDDING.getState().equals(member.getInteriorAdutState()));
        //3.所有报名至少有一个审核通过
        boolean b = materiels.stream().allMatch(member -> OnlineAudteExternalStateEnum.SIGNUP_BIDDING_NOT.getState().equals(member.getExternalAdutState()));
        if (materiels.size() == 0 || a || b){
            bidding.setInteriorState(BiddingInteriorWorkStateEnum.CANCEL.getState());
            bidding.setExternalState(BiddingExternalWorkStateEnum.CANCEL.getState());
            bidding.setDiscardTime(millis);
            String discardCause = materiels.size() == 0 ? CancelReasonStateEnum.NO_ONE_SIGNED_UP.getName() : a? CancelReasonStateEnum.REGISTRATION_PROCESS_NOT_APPROVED.getName() : CancelReasonStateEnum.PROCESS_NOT_APPROVED.getName();
            bidding.setDiscardCause(discardCause);
            bidding.setUpdateTime(millis);
            biddingRepository.saveAndFlush(bidding);
            //在线竞价实体
            onLineBidding.setInteriorState(OnlineInteriorWorkStateEnum.CANCEL.getState());
            onLineBidding.setExternalState(OnlineBiddingExternalWorkStateEnum.CANCEL.getState());
            onLineBidding.setUpdateTime(millis);
            //批量设置所有竞价供应商状态为已作废
            savaCancelStatus(onLineBidding);
            onLineBiddingRepository.saveAndFlush(onLineBidding);

            //采购单在线竞价单内部流转记录
            UserLoginCacheDTO sysUser = new UserLoginCacheDTO();
            //操作人为admin
            sysUser.setUserJobTitle("admin");
            sysUser.setMemberRoleName("admin");
            onlineBiddinService.initOnlineInteriorLog(sysUser, BiddingOperationStateEnum.CANCEL.getState(), onLineBidding.getInteriorState(), onLineBidding.getId(), discardCause);
            //采购单外部流转记录
            saveExternalLog(sysUser, BiddingOperationStateEnum.CANCEL.getState(), bidding.getExternalState(), bidding.getId(), null, discardCause, null, null);
            //采购单内部流转记录
            saveInteriorLog(sysUser, BiddingOperationStateEnum.CANCEL.getState(), bidding.getInteriorState(), null, bidding.getId(), discardCause);
            return;
        }

        //外部工作流执行两个流程 到待竞价
        //执行外部工作流
//        Wrapper<ComplexTaskCompleteVO> taskCompleteVOWrapper = executeWorks(request.getMemberId(), request.getMemberRoleId(), request.getId(), ProcessEnum.PURCHASE_BIDDING_EXTERNAL.getCode(), bidding.getExternalNextStep(), bidding.getExternalTaskId(), Arrays.asList(OrderConstant.Auditing.DEFAULT, OrderConstant.Auditing.DEFAULT), 2);
//        if (ResponseCode.SUCCESS.getCode() != taskCompleteVOWrapper.getCode()) {
//            throw new RuntimeException(taskCompleteVOWrapper.getMessage());
//        }
        Wrapper<SimpleTaskCompleteVO> taskResult1 = executeWork(request.getMemberId(), request.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_EXTERNAL.getCode(), bidding.getExternalNextStep(), bidding.getExternalTaskId(), OrderConstant.Auditing.DEFAULT);
        if (ResponseCode.SUCCESS.getCode() != taskResult1.getCode()) {
            throw new RuntimeException(taskResult1.getMessage());
        }
        Wrapper<SimpleTaskCompleteVO> taskResult2 = executeWork(request.getMemberId(), request.getMemberRoleId(), bidding.getId(), ProcessEnum.PURCHASE_BIDDING_EXTERNAL.getCode(), bidding.getExternalNextStep(), taskResult1.getData().getTaskId(), OrderConstant.Auditing.PASS);
        if (ResponseCode.SUCCESS.getCode() != taskResult2.getCode()) {
            throw new RuntimeException(taskResult2.getMessage());
        }
        //内部流程执行下一步工作流
        bidding.setExternalTaskId(taskResult2.getData().getTaskId());
        bidding.setExternalState(taskResult2.getData().getStatus());
        bidding.setExternalNextStep(taskResult2.getData().getStep());
        bidding.setInteriorState(BiddingInteriorWorkStateEnum.SIGNUP_EXAMIN_NOT2.getState());
        bidding.setUpdateTime(millis);
        onLineBidding.setUpdateTime(millis);
        onLineBidding.setExternalState(OnlineBiddingExternalWorkStateEnum.STAY_BIDDING.getState());
        onLineBidding.setInteriorState(OnlineInteriorWorkStateEnum.WAITING_FOR_BIDDING.getState());
        //设置报名审核通过会员竞价状态为待竞价
        materiels.forEach(materiel ->{
            if(OnlineAudteExternalStateEnum.SIGNUP_BIDDING_PASS.getState().equals(materiel.getExternalAdutState())){
                materiel.setInteriorState(OnlineInteriorWorkStateEnum.WAITING_FOR_BIDDING.getState());
                materiel.setExternalState(OnlineBiddingExternalWorkStateEnum.STAY_BIDDING.getState());
            }
        });
        biddingRepository.saveAndFlush(bidding);
        //添加MQ任务处理竞价时间截止后续工作流
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void afterCommit() {
                log.info("竞价截止>准备添加延时队列 BiddingId:{}", bidding.getId());
                // 结束竞价
                sendRabbitMqEnd(bidding);
                log.info("竞价截止>添加延时队列完成 BiddingId:{}", bidding.getId());
            }
        });
    }

    /**
     * MQ延时任务处理竞价结束业务
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void examineSignUpEnd(OrderRbbitMqRequest request, Message message, Channel channel) {
        //竞价单
        Bidding bidding = biddingRepository.findById(request.getId()).orElse(null);
        if (ObjectUtils.isEmpty(bidding)) {
            log.error("未找到竞价单信息, 单号:{}", request.getId());
            return;
        }
        //报价单
        OnLineBidding onLineBidding = onLineBiddingRepository.findFirstByBiddingId(bidding.getId());
        if (ObjectUtils.isEmpty(onLineBidding)) {
            log.error("未找到在线竞价单信息, 单号:{}", request.getId());
            return;
        }
        //是否已作废
        if (BiddingExternalWorkStateEnum.CANCEL.getState().equals(bidding.getExternalState()) || BiddingExternalWorkStateEnum.CANCEL.getState().equals(onLineBidding.getExternalState())){
            log.error("竞价单已作废, 单号:{}", request.getId());
            return;
        }
        if (!BiddingExternalWorkStateEnum.STAY_BIDDING.getState().equals(bidding.getExternalState())){
            log.error("竞价单外部状态不是待竞价, 单号:{}", request.getId());
            return;
        }
        //判断单据状态是否可以执行与到期时间是否大于当前时间
        if (System.currentTimeMillis() < bidding.getBiddingEndTime()) {
            throw new RuntimeException(ResponseCode.REGISTRATION_RE_CONSUMPTION.getMessage());
        }
        //作废竞价单
        //1.判断是否有人竞价 无人竞价的话 自动作废该竞价单
        List<OnlineMateriel> materiels = onlineMaterielRepository.findAllByOnlineBiddingIdAndIsSignUp(onLineBidding.getId(), StatusEnum.YES.getState());
        boolean result = materiels.stream().allMatch(member -> StatusEnum.NO.getState().equals(member.getIsOffer()));
        if (result){
            long time = System.currentTimeMillis();
            bidding.setInteriorState(BiddingInteriorWorkStateEnum.CANCEL.getState());
            bidding.setExternalState(BiddingExternalWorkStateEnum.CANCEL.getState());
            bidding.setDiscardTime(time);
            String discardCause = CancelReasonStateEnum.NO_QUOTATION_AS_OF.getName();
            bidding.setDiscardCause(discardCause);
            bidding.setUpdateTime(time);
            biddingRepository.saveAndFlush(bidding);
            //在线竞价实体
            onLineBidding.setInteriorState(OnlineInteriorWorkStateEnum.CANCEL.getState());
            onLineBidding.setExternalState(OnlineBiddingExternalWorkStateEnum.CANCEL.getState());
            onLineBidding.setUpdateTime(time);
            //批量设置所有竞价供应商状态为已作废
            savaCancelStatus(onLineBidding);
            onLineBiddingRepository.saveAndFlush(onLineBidding);

            //采购单在线竞价单内部流转记录
            UserLoginCacheDTO sysUser = new UserLoginCacheDTO();
            //操作人为admin
            sysUser.setUserJobTitle("admin");
            sysUser.setMemberRoleName("admin");
            onlineBiddinService.initOnlineInteriorLog(sysUser, BiddingOperationStateEnum.CANCEL.getState(), onLineBidding.getInteriorState(), onLineBidding.getId(), discardCause);
            //采购单内部流转记录
            saveInteriorLog(sysUser, BiddingOperationStateEnum.CANCEL.getState(), bidding.getInteriorState(), null, bidding.getId(), "");
            //采购单外部流转记录
            saveExternalLog(sysUser, BiddingOperationStateEnum.CANCEL.getState(), bidding.getExternalState(), bidding.getId(), null, discardCause, null, null);
            return;
        }
        //进行授标信息处理
        updateRanking(materiels, onLineBidding);
        //执行外部工作流
        Wrapper<SimpleTaskCompleteVO> externalTaskResult = executeWork(request.getMemberId(), request.getMemberRoleId(), request.getId(), ProcessEnum.PURCHASE_BIDDING_EXTERNAL.getCode(), bidding.getExternalNextStep(), bidding.getExternalTaskId(), OrderConstant.Auditing.DEFAULT);
        if (ResponseCode.SUCCESS.getCode() != externalTaskResult.getCode()) {
            throw new RuntimeException(externalTaskResult.getMessage());
        }

        //启动内部工作流
        UserLoginCacheDTO sysUser = new UserLoginCacheDTO();
        sysUser.setMemberId(onLineBidding.getMemberId());
        sysUser.setMemberRoleId(onLineBidding.getMemberRoleId());
        Wrapper<SimpleTaskCompleteVO> taskResult = startWork(sysUser, bidding.getId(), ProcessEnum.PURCHASE_BIDDING_EXAMINE_INTERIOR.getCode());
        if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
            throw new BusinessException(taskResult.getMessage());
        }
        bidding.setAuditInteriorTaskId(taskResult.getData().getTaskId());
        bidding.setAuditInteriorState(taskResult.getData().getStatus());
        bidding.setAuditInteriorNextStep(taskResult.getData().getStep());
        bidding.setInteriorState(taskResult.getData().getStatus());
        bidding.setExternalTaskId(externalTaskResult.getData().getTaskId());
        bidding.setExternalState(externalTaskResult.getData().getStatus());
        bidding.setExternalNextStep(externalTaskResult.getData().getStep());
        //设置报名审核通过会员外部状态为待确认竞价结果
        materiels.forEach(materiel ->{
            if(OnlineAudteExternalStateEnum.SIGNUP_BIDDING_PASS.getState().equals(materiel.getExternalAdutState())){
                materiel.setExternalState(OnlineBiddingExternalWorkStateEnum.BIDDING_CONFIRM_RETURN.getState());
                //根据是否竞价设置内部状态
                if (StatusEnum.YES.getState().equals(materiel.getIsOffer())){
                    materiel.setInteriorState(OnlineInteriorWorkStateEnum.ALREADY_BIDDING.getState());
                }
            }
        });
        //记录操作记录
        ExternalBiddingLog externalLog = new ExternalBiddingLog();
        externalLog.setRoleName(getRoleNameById(request.getMemberRoleId()));
        externalLog.setBiddingId(request.getId());
        externalLog.setState(externalTaskResult.getData().getStatus());
        externalLog.setOperation(BiddingOperationStateEnum.ADMINISTRATION_BIDDING.getState());
        externalLog.setAuditOpinion("");
        externalLog.setCreateTime(System.currentTimeMillis());
        externalLog.setCreateMemberId(request.getMemberId());
        externalLog.setCreateMemberRoleId(request.getMemberRoleId());
        externalBiddingLogRepository.saveAndFlush(externalLog);
        biddingRepository.saveAndFlush(bidding);
        //清除redis数据
        redisStringUtils.del(PurchaseInquiryConstant.BIDDING_RANKING_LIST_KEY + onLineBidding.getId() + "", Constants.REDIS_USER_INDEX);
        redisStringUtils.del(PurchaseInquiryConstant.BIDDING_RANKING_LIST_DETAILS + onLineBidding.getId() + "", Constants.PURCHASE_INDEX);
        redisStringUtils.del(PurchaseInquiryConstant.BIDDING_RANKING_COUNT_KEY + onLineBidding.getId() + "", Constants.PURCHASE_INDEX);
    }

    /**
     * 采购商机筛选-竞价单查询
     */
    @Override
    public Wrapper<PageData<PurchaseListResponse>> businessPpportunityBiddingList(PurchaseListRequest request) {
        //查询商城为企业商城且商城环境为WEB的shopID
        long shopId = 1L;
        Wrapper<List<ShopVO>> listWrapper = shopControllerFeign.findAllByShopTypeAndEnvironment(ShopTypeEnum.ENTERPRISE.getCode(), ShopEnvironmentEnum.WEB.getCode());
        if (ResponseCode.SUCCESS.getCode() == listWrapper.getCode() && !CollectionUtils.isEmpty(listWrapper.getData())) {
            shopId = listWrapper.getData().get(0).getId();
        }
        Wrapper<PageData<PurchaseListResponse>> pageDataWrapper = queryList(request, shopId);
        if (ResponseCode.SUCCESS.getCode() != pageDataWrapper.getCode() || CollectionUtils.isEmpty(pageDataWrapper.getData().getData())) {
            return pageDataWrapper;
        }
        //聚合统计单据的物料总数、分类
        List<PurchaseListResponse> data = pageDataWrapper.getData().getData();
        //筛选shopId包含web企业商城的
        final long finalShopId = shopId;
        data = data.stream().filter(purchase -> !CollectionUtils.isEmpty(purchase.getShopIds()) && purchase.getShopIds().contains(finalShopId)).collect(Collectors.toList());
        Map<Long, List<PurchaseListResponse>> collect = data.stream().collect(Collectors.groupingBy(PurchaseListResponse::getId));
        List<PurchaseListResponse> purchaseList = new ArrayList<>();
        for (Long id : collect.keySet()) {
            List<PurchaseListResponse> purchaseListResponses = collect.get(id);
            PurchaseListResponse purchaseListResponse = purchaseListResponses.get(0);
            //获得物料总和
            int size = purchaseListResponses.stream().map(PurchaseListResponse::getProductId).collect(Collectors.toSet()).size();
            purchaseListResponse.setCount(size);
            //获得分类集合
            Set<String> ids = purchaseListResponses.stream().map(PurchaseListResponse::getCategory).collect(Collectors.toSet());
            if (!CollectionUtils.isEmpty(ids)) {
                purchaseListResponse.setCategory(StringUtils.collectionToDelimitedString(ids, "、"));
            }
            if(!ObjectUtils.isEmpty(purchaseListResponse)){
                purchaseListResponse.setCreateTimeStr(DateUtil.timeStamp2Date(purchaseListResponse.getCreateTime(),"yyyy-MM-dd HH:mm"));
                purchaseListResponse.setDeliveryTimeStr(DateUtil.timeStamp2Date(purchaseListResponse.getDeliveryTime(),"yyyy-MM-dd HH:mm"));
                purchaseListResponse.setDays(0<=DateUtil.judgeTime(purchaseListResponse.getOfferEndTime())[0]?DateUtil.judgeTime(purchaseListResponse.getOfferEndTime())[0]:0);
                purchaseListResponse.setHours(0<=DateUtil.judgeTime(purchaseListResponse.getOfferEndTime())[1]?DateUtil.judgeTime(purchaseListResponse.getOfferEndTime())[1]:0);
                purchaseListResponse.setMinutes(0<=DateUtil.judgeTime(purchaseListResponse.getOfferEndTime())[2]?DateUtil.judgeTime(purchaseListResponse.getOfferEndTime())[2]:0);
            }
            purchaseList.add(purchaseListResponse);
        }
        //分页
        List<PurchaseListResponse> purchaseListResponses = CollectionPageUtil.pageList(purchaseList, request.getCurrent() + 1, request.getPageSize());
        pageDataWrapper.getData().setData(purchaseListResponses);
        return Wrapper.success(new PageData<>((long) purchaseList.size(), purchaseListResponses));
    }

    /**
     * 采购公示
     */
    @Override
    public Wrapper<PageData<PurchaseMakeList>> purchaseMakeList(PurchaseMakeListRequest request) {
        List<PurchaseMakeList> responses;
        QBidding qBidding = QBidding.bidding;
        QOnLineBidding onLineBidding = QOnLineBidding.onLineBidding;
        // 定于获取条件
        BooleanBuilder predicates = new BooleanBuilder();
        if (StringUtils.hasLength(request.getDetails())) {
            predicates.and(qBidding.details.like("%" + request.getDetails() + "%"));
        }
        if (null != request.getMemberId() && null != request.getMemberRoleId()) {
            predicates.and(qBidding.createMemberId.eq(request.getMemberId()));
            predicates.and(qBidding.createMemberRoleId.eq(request.getMemberRoleId()));
        }
        predicates.and(onLineBidding.notice.eq(PurchaseInquiryConstant.State.START));
        JPAQuery<PurchaseMakeList> query = queryFactory.select(Projections.bean(PurchaseMakeList.class,
                qBidding.id,
                onLineBidding.awardResults.as("context"),
                qBidding.details.as("pojoName"),
                qBidding.createMemberName.as("enterpriseName"),
                qBidding.updateTime.as("releaseTime")
        )).from(qBidding)
                .leftJoin(onLineBidding)
                .on(qBidding.id.eq(onLineBidding.bidding.id))
                .where(predicates);
        long totalCount = query.fetchCount();
        responses = query.orderBy(qBidding.updateTime.desc())
                .offset((request.getCurrent() - 1) * request.getPageSize())
                .limit(request.getPageSize())
                .fetch();
        if(!CollectionUtils.isEmpty(responses)){
            responses.forEach(temp->{
                temp.setReleaseTimeStr(DateUtil.timeStamp2Date(temp.getReleaseTime(),"yyyy-MM-dd HH:mm"));
            });
        }
        return Wrapper.success(new PageData<>(totalCount, responses));
    }

    /**
     * 商城能力--企业直采--采购门户--采购寻源筛选-接口
     */
    @Override
    public Wrapper<PageData<SearchReSourceListResponse>> searchReSourceList(PurchaseListRequest request, Long shopId, UserLoginCacheDTO sysUser) {
        //查询商城为企业商城且商城环境为WEB的shopID
//        long shopId = 1L;
//        Wrapper<List<ShopResponse>> listWrapper = shopControllerFeign.findAllByShopTypeAndEnvironment(ShopTypeEnum.Enterprise.getCode(), ShopEnvironmentEnum.WEB.getCode());
//        if (ResponseCode.SUCCESS.getCode() == listWrapper.getCode() && !CollectionUtils.isEmpty(listWrapper.getData())) {
//            shopId = listWrapper.getData().get(0).getId();
//        }
        List<SearchReSourceListResponse> responses;
        List<SearchReSourceInstantaneousVO> instantaneous;
        QBidding qBidding = QBidding.bidding;
        QBiddingArea qBiddingArea = QBiddingArea.biddingArea;
        QBiddingProduct qBiddingProduct = QBiddingProduct.biddingProduct;
        // 定于获取条件
        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(qBidding.externalState.notIn(BiddingExternalWorkStateEnum.CANCEL.getState(), BiddingExternalWorkStateEnum.STAY_SUBMIT_BIDDING.getState()));
        predicates.and(qBidding.type.eq(PurchaseInquiryConstant.type.PLATFORM));
        if (StringUtils.hasLength(request.getKeyword())) {
            predicates.and(qBidding.details.like("%" + request.getKeyword() + "%").or(qBiddingProduct.category.like("%" + request.getKeyword() + "%")));
        }
        if (null != request.getStartTime()) {
            predicates.and(qBidding.createTime.goe(request.getStartTime()));
        }
        if (null != request.getEndTime()) {
            predicates.and(qBidding.createTime.loe(request.getStartTime()));
        }
        if (null != request.getCategory()) {
            predicates.and(qBiddingProduct.category.like("%" + request.getCategory() + "%"));
        }
        if (OrderConstant.State.START.equals(request.getOverdue())) {
            predicates.and(qBidding.endSignUp.goe(System.currentTimeMillis()));
        }
        //貌似没用上
        if (!ObjectUtils.isEmpty(request.getArea())) {
            if (StringUtils.hasLength(request.getArea().getAreaCode())) {
                predicates.and(qBiddingArea.areaCode.eq(request.getArea().getAreaCode()));
            }
            if (StringUtils.hasLength(request.getArea().getCityCode())) {
                predicates.and(qBiddingArea.cityCode.eq(request.getArea().getCityCode()));
            }
            if (StringUtils.hasLength(request.getArea().getProvinceCode())) {
                predicates.and(qBiddingArea.provinceCode.eq(request.getArea().getProvinceCode()));
            }
        }
        if(request.getMemberId() != null){
            predicates.and(qBidding.createMemberId.eq(request.getMemberId()));
        }
        if (request.getMemberRoleId() !=null){
            predicates.and(qBidding.createMemberRoleId.eq(request.getMemberRoleId()));
        }
        if (StringUtils.hasLength(request.getCityCode())) {
            predicates.and(qBiddingArea.cityCode.eq(request.getCityCode()).or(qBiddingArea.cityCode.eq("")));
        }
        if (StringUtils.hasLength(request.getProvinceCode())) {
            predicates.and(qBiddingArea.provinceCode.eq(request.getProvinceCode()).or(qBiddingArea.provinceCode.eq("")));
        }
        JPAQuery<SearchReSourceInstantaneousVO> query = queryFactory.select(Projections.bean(SearchReSourceInstantaneousVO.class,
                qBidding.id,
                qBidding.biddingNo.as("purchaseInquiryNo"),
                qBidding.details,
                qBidding.createTime,
                qBidding.shopIds,
                qBidding.deliver.as("deliveryTime"),
                qBidding.endSignUp.as("offerEndTime"),
                qBidding.address,
                qBidding.addressId,
                qBidding.createMemberId.as("memberId"),
                qBidding.createMemberName.as("memberName"),
                qBidding.createMemberRoleId.as("memberRoleId"),
                qBiddingProduct.id.as("productId"),
                qBiddingProduct.category,
                qBiddingArea.provinceCode,
                qBiddingArea.province,
                qBiddingArea.cityCode,
                qBiddingArea.city,
                qBiddingArea.areaCode,
                qBiddingArea.area,
                qBiddingArea.address.as("detailAddress")
                )).from(qBidding)
                .leftJoin(qBiddingProduct)
                .on(qBidding.id.eq(qBiddingProduct.bidding.id))
                .leftJoin(qBiddingArea)
                .on(qBidding.id.eq(qBiddingArea.bidding.id))
                .where(predicates);
        instantaneous = query.orderBy(qBidding.createTime.desc())
                .fetch();
        //筛选shopId包含web企业商城的 聚合统计单据的物料总数、分类
//        final long finalShopId = shopId;
        instantaneous = instantaneous.stream().filter(purchase -> !CollectionUtils.isEmpty(purchase.getShopIds()) && purchase.getShopIds().contains(shopId)).collect(Collectors.toList());
        Map<Long, List<SearchReSourceInstantaneousVO>> collect = instantaneous.stream().collect(Collectors.groupingBy(SearchReSourceInstantaneousVO::getId));
        List<SearchReSourceListResponse> purchaseList = new ArrayList<>();
        for (Long id : collect.keySet()) {
            List<SearchReSourceInstantaneousVO> purchaseListResponses = collect.get(id);
            SearchReSourceInstantaneousVO purchaseListResponse = purchaseListResponses.get(0);
            //获得物料总和
            int size = purchaseListResponses.stream().map(SearchReSourceInstantaneousVO::getProductId).collect(Collectors.toSet()).size();
            purchaseListResponse.setCount(size);
            //获得分类集合
            Set<String> ids = purchaseListResponses.stream().map(SearchReSourceInstantaneousVO::getCategory).collect(Collectors.toSet());
            if (!CollectionUtils.isEmpty(ids)) {
                purchaseListResponse.setCategory(StringUtils.collectionToDelimitedString(ids, "、"));
            }
            if(!ObjectUtils.isEmpty(purchaseListResponse)){
                purchaseListResponse.setCreateTimeStr(DateUtil.timeStamp2Date(purchaseListResponse.getCreateTime(),"yyyy-MM-dd HH:mm"));
                purchaseListResponse.setDeliveryTimeStr(DateUtil.timeStamp2Date(purchaseListResponse.getDeliveryTime(),"yyyy-MM-dd HH:mm"));
                purchaseListResponse.setDays(0<=DateUtil.judgeTime(purchaseListResponse.getOfferEndTime())[0]?DateUtil.judgeTime(purchaseListResponse.getOfferEndTime())[0]:0);
                purchaseListResponse.setHours(0<=DateUtil.judgeTime(purchaseListResponse.getOfferEndTime())[1]?DateUtil.judgeTime(purchaseListResponse.getOfferEndTime())[1]:0);
                purchaseListResponse.setMinutes(0<=DateUtil.judgeTime(purchaseListResponse.getOfferEndTime())[2]?DateUtil.judgeTime(purchaseListResponse.getOfferEndTime())[2]:0);
            }
            //适用地市组装
            List<CountryArea> areas = purchaseListResponses.stream().map(predicate ->{
                CountryArea area = BeanUtil.copyProperties(predicate, CountryArea.class);
                area.setAddress(predicate.getDetailAddress());
                return area;
            }).collect(Collectors.toList());
            purchaseListResponse.setAreas(areas);
            SearchReSourceListResponse response = BeanUtil.copyProperties(purchaseListResponse, SearchReSourceListResponse.class);
            //判断当前登录会员是否有报名
            OnLineBidding onLineBidding = onLineBiddingRepository.findFirstByBiddingId(response.getId());
            OnlineMateriel onlineMateriel = onlineMaterielRepository.findByOnlineBiddingAndCreateMemberIdAndCreateMemberRoleId(onLineBidding, sysUser.getMemberId(), sysUser.getMemberRoleId());
            response.setIsSignUp(Objects.nonNull(onlineMateriel) ? onlineMateriel.getIsSignUp() : 0);
            //判断是否是自己创建的竞价单, 同时判断是否是采购商角色
            response.setIsMePublish((response.getMemberId().equals(sysUser.getMemberId()) && response.getMemberRoleId().equals(sysUser.getMemberRoleId())) || RoleTypeEnum.SERVICE_CONSUMER.getCode().equals(sysUser.getMemberRoleType()) ? 1 : 0);
            purchaseList.add(response);
        }
        //分页
        List<SearchReSourceListResponse> purchaseListResponses = CollectionPageUtil.pageList(purchaseList, request.getCurrent() + 1, request.getPageSize());
        if (!CollectionUtils.isEmpty(purchaseListResponses)) {
            //查询详情
            List<BiddingProduct> products = biddingProductRepository.findAllByBiddingIdIn(purchaseListResponses.stream().map(SearchReSourceListResponse::getId).collect(Collectors.toSet()));
            if (!CollectionUtils.isEmpty(products)) {
                List<SearchReSourceDetailsResponse> searchReSourceDetailss = products.stream().map(temp -> {
                    SearchReSourceDetailsResponse searchReSourceDetails = new SearchReSourceDetailsResponse();
                    Bidding bidding = temp.getBidding();
                    searchReSourceDetails.setPurchaseInquiryId(bidding.getId());
                    searchReSourceDetails.setBrand(temp.getBrand());
                    searchReSourceDetails.setId(temp.getId());
                    searchReSourceDetails.setNumber(temp.getNumber());
                    searchReSourceDetails.setName(temp.getName());
                    searchReSourceDetails.setModel(temp.getModel());
                    searchReSourceDetails.setCategory(temp.getCategory());
                    searchReSourceDetails.setUnit(temp.getUnit());
                    searchReSourceDetails.setPurchaseCount(temp.getPurchaseCount());
                    return searchReSourceDetails;
                }).collect(Collectors.toList());
                Map<Long, List<SearchReSourceDetailsResponse>> productMap = searchReSourceDetailss.stream().collect(Collectors.groupingBy(SearchReSourceDetailsResponse::getPurchaseInquiryId));
                purchaseListResponses.forEach(temp -> {
                    temp.setMateriels(productMap.get(temp.getId()));
                });
            }
        }
        purchaseListResponses= purchaseListResponses.stream().sorted(Comparator.comparing(SearchReSourceListResponse::getCreateTime).reversed()).collect(Collectors.toList());
        return Wrapper.success(new PageData<>((long) purchaseList.size(), purchaseListResponses));
    }

    /**
     * 采购寻源--采购竞价--采购竞价详情
     */
    @Override
    public Wrapper<BiddingDetailsResponse> searchReSourceDetails(BaseDetailsRequest request, UserLoginCacheDTO sysUser) {
        BiddingDetailsResponse response = new BiddingDetailsResponse();
        Bidding bidding;
        if (null != request.getId()) {
            bidding = biddingRepository.findById(request.getId()).orElse(null);
        } else {
            bidding = biddingRepository.findByBiddingNo(request.getNumber());
        }
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        OnLineBidding onLineBidding = onLineBiddingRepository.findFirstByBiddingId(bidding.getId());
        if (ObjectUtils.isEmpty(onLineBidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        //当前竞价会员
        OnlineMateriel materiel = onlineMaterielRepository.findByOnlineBiddingAndCreateMemberIdAndCreateMemberRoleId(onLineBidding, sysUser.getMemberId(), sysUser.getMemberRoleId());
        if (!ObjectUtils.isEmpty(materiel)) {
//            return Wrapper.fail(ResponseCode.NOT_ELIGIBLE_FOR_BIDDING);
            //供应商是否有竞价资格
            response.setCanRegister(OnlineAudteInteriorStateEnum.BIDDING_SIGNUP_HAS_BEEN_SIGNED_UP.getState().equals(materiel.getInteriorAdutState()) && OnlineAudteExternalStateEnum.SIGNUP_BIDDING_PASS.getState().equals(materiel.getExternalAdutState())? 1 : 0);
            response.setIsRegister(materiel.getIsOffer());
            response.setIsSignUp(materiel.getIsSignUp());
            Integer count = bidding.getAllowPurchaseCount();
            Long peportPriceSum = materiel.getPeportPriceSum();
            response.setTurn(peportPriceSum == null? count : (int) (count - peportPriceSum));
        }
        BeanUtils.copyProperties(bidding, response);
        response.setInteriorStateName(BiddingInteriorWorkStateEnum.getName(bidding.getInteriorState()));
        response.setExternalStateName(BiddingExternalWorkStateEnum.getName(bidding.getExternalState()));
        response.setAreas(bidding.getAreas().stream().map(temp -> {
            CountryAreaResponse countryArea = new CountryAreaResponse();
            BeanUtils.copyProperties(temp, countryArea);
            return countryArea;
        }).collect(Collectors.toList()));
        Long id = bidding.getId();
        //查询采购竞价单物料信息列表
        response.setMateriels(getMateriels(id));
        //组装截止时间给前端
        response.setDays(0<=DateUtil.judgeTime(response.getBiddingEndTime())[0]?DateUtil.judgeTime(response.getBiddingEndTime())[0]:0);
        response.setHours(0<=DateUtil.judgeTime(response.getBiddingEndTime())[1]?DateUtil.judgeTime(response.getBiddingEndTime())[1]:0);
        response.setMinutes(0<=DateUtil.judgeTime(response.getBiddingEndTime())[2]?DateUtil.judgeTime(response.getBiddingEndTime())[2]:0);
        //判断是否是自己创建的竞价单, 同时判断是否是采购商角色
        response.setIsMePublish((response.getCreateMemberId().equals(sysUser.getMemberId()) && response.getCreateMemberRoleId().equals(sysUser.getMemberRoleId())) || RoleTypeEnum.SERVICE_CONSUMER.getCode().equals(sysUser.getMemberRoleType()) ? 1 : 0);
        return Wrapper.success(response);
    }

    /**
     * 采购物料分页查询-采购寻源--采购竞价--采购竞价详情
     */
    @Override
    public Wrapper<PageData<BiddingProductRequest>> searchSourceMaterielPage(BaseDetailsRequest request) {
        Bidding bidding;
        if (null != request.getId()) {
            bidding = biddingRepository.findById(request.getId()).orElse(null);
        } else {
            bidding = biddingRepository.findByBiddingNo(request.getNumber());
        }
        if (ObjectUtils.isEmpty(bidding)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        Long id = bidding.getId();
        Page<BiddingProduct> biddingProducts = biddingProductRepository.findAllByBiddingId(id, PageRequest.of(request.getCurrent(), request.getPageSize(), Sort.by("id").ascending()));
        long count = biddingProducts.getTotalElements();
        if (0 == count) {
            return Wrapper.success(new PageData<>(count, new ArrayList<>()));
        }
        List<BiddingProductRequest> collect = biddingProducts.getContent().stream().map(temp -> {
            BiddingProductRequest response = new BiddingProductRequest();
            BeanUtils.copyProperties(temp, response);
            response.setItemNo(temp.getItemNo());
            return response;
        }).collect(Collectors.toList());
        return Wrapper.success(new PageData<>(biddingProducts.getTotalElements(), collect));
    }

    /**
     *分页查询在线竞标-中标的采购物料
     */
    @Override
    public PageData<OnLineBiddingProduct> prizeMaterielPage(PageVO pageVO, Long id) {
        if (id != null && id > 0) {
            OnLineBidding onLineBidding = onLineBiddingRepository.findFirstByBiddingId(id);
            if (Objects.isNull(onLineBidding)) {
                throw new BusinessException(ResponseCode.PURCHASE_BIDDING_IS_NOT_EXISTS);
            }
            //竞价会员信息
            List<OnlineMateriel> materiels = onlineMaterielRepository.findAllByOnlineBiddingIdAndIsSignUp(onLineBidding.getId(), StatusEnum.YES.getState());
            if (CollectionUtils.isEmpty(materiels)) {
                return new PageData<>(0L, new ArrayList<>());
            }
            for (OnlineMateriel materiel : materiels) {
                Integer isPrize = materiel.getIsPrize();
                if (isPrize != null && isPrize == 1) {
                    //查询最后中标物料
                    Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize());
                    Page<OnLineBiddingProduct> products = productRepository.findAllByOnlineMaterielAndReportNumber(materiel, materiel.getPeportPriceSum(), page);
                    return new PageData<>(products.getTotalElements(), products.getContent());
                }
            }
            return new PageData<>(0L, null);
        }
        throw new BusinessException(ResponseCode.PURCHASE_BIDDING_IS_NOT_EXISTS);
    }

    /**
     * 记录报价单最后的排名  设置排名第一中标其他为不中标并且更新其排名
     */
    private void updateRanking(List<OnlineMateriel> materiels, OnLineBidding onLineBidding) {
        Long biddingId = onLineBidding.getId();
        //获得所有排名
        List<Map<String, Double>> scoreList = redisStringUtils.rangeWithScoresOrderByScore(PurchaseInquiryConstant.BIDDING_RANKING_LIST_KEY + biddingId, 0, materiels.size());
        //无人报价
        if (CollectionUtils.isEmpty(scoreList)) {
            log.error("[竞价延时队列]无人报价，竞价单id:{}",biddingId);
            return;
        }
        Map<String, OnlineMateriel> collect = materiels.stream().collect(Collectors.toMap(materiel -> materiel.getCreateMemberId() + "_" + materiel.getCreateMemberRoleId(), materiel -> materiel));
        //获得排名第一的报价会员信息
        Map<String, Double> map = scoreList.get(0);
        String onlineIdStr = map.keySet().stream().findFirst().orElse(null);
        OnlineMateriel onlineMateriel = collect.get(onlineIdStr);

        for (int i = 0; i < scoreList.size(); i++) {
            Map<String, Double> onLineBiddingMap = scoreList.get(i);
            String key = onLineBiddingMap.keySet().stream().findFirst().orElse(null);
            OnlineMateriel materiel = collect.get(key);
            log.info("[竞价延时队列]设置中标会员：onlineId：{}, 会员名称:{}", biddingId, materiel.getCreateMemberName());
            materiel.setIsPrize(OrderConstant.State.STOP);
            //最终排名
            materiel.setPurchaseRanking((long) (i + 1));
        }
        //第一名默认设为授标
        onlineMateriel.setIsPrize(OrderConstant.State.START);
        //最终授标总额
        List<OnLineBiddingProduct> products = productRepository.findAllByOnlineMaterielAndReportNumber(onlineMateriel, onlineMateriel.getPeportPriceSum());
        if (CollectionUtils.isEmpty(products)){
            log.error("[竞价延时队列]未查询到供应商竞价物料信息，竞价单id:{}，竞价会员onlineMaterielId:{}" ,biddingId, onlineMateriel.getId());
            throw new RuntimeException(ResponseCode.EXCEL_UPLOAD_ERROR_NULL.getMessage());
        }
        onlineMateriel.setPrice(products.stream().mapToDouble(OnLineBiddingProduct::getPrice).sum());
        //设置授标消息
        onLineBidding.setSumAwardPrice(onlineMateriel.getPrice());
        onLineBidding.setMemberId(onlineMateriel.getCreateMemberId());
        onLineBidding.setMemberName(onlineMateriel.getCreateMemberName());
        onLineBidding.setMemberRoleId(onlineMateriel.getCreateMemberRoleId());
        onlineMaterielRepository.saveAll(materiels);
    }

    /**
     * 结束竞价-待审核竞价结果
     */
    public void sendRabbitMqEnd(Bidding bidding) {
        //发送MQ定时处理报名时间业务
        OrderRbbitMqRequest rbbitMqRequest = new OrderRbbitMqRequest();
        rbbitMqRequest.setId(bidding.getId());
        rbbitMqRequest.setMemberId(bidding.getCreateMemberId());
        rbbitMqRequest.setMemberRoleId(bidding.getCreateMemberRoleId());
        rbbitMqRequest.setExpirationTime(bidding.getBiddingEndTime());
        rabbitMQProvider.sendDelayMessage(rbbitMqRequest, MessageConstants.PURCHASE_END_BIDDING_DELAY_EXCHANGE, MessageConstants.PURCHASE_END_BIDDING_DELAY_KEY, 2L);
    }


    /**
     * 查询竞价单列表根据查询类型查询
     */
    private Wrapper<PageData<PurchaseListResponse>> queryList(PurchaseListRequest request, Long shopId) {
        List<PurchaseListResponse> responses;
        QBidding qBidding = QBidding.bidding;
        QBiddingArea qBiddingArea = QBiddingArea.biddingArea;
        QBiddingProduct qBiddingProduct = QBiddingProduct.biddingProduct;
        // 定于获取条件
        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(qBidding.type.eq(PurchaseInquiryConstant.type.PLATFORM));
        if (null != request.getStartTime()) {
            predicates.and(qBidding.createTime.goe(request.getStartTime()));
        }
        if (null != request.getEndTime()) {
            predicates.and(qBidding.createTime.loe(request.getStartTime()));
        }
        if (null != request.getCategory()) {
            predicates.and(qBiddingProduct.category.like("%" + request.getCategory() + "%"));
        }
        if (OrderConstant.State.START.equals(request.getOverdue())) {
            predicates.and(qBidding.endSignUp.goe(System.currentTimeMillis()));
        }
        if (!ObjectUtils.isEmpty(request.getArea())) {
            if (StringUtils.hasLength(request.getArea().getAreaCode())) {
                predicates.and(qBiddingArea.areaCode.eq(request.getArea().getAreaCode()));
            }
            if (StringUtils.hasLength(request.getArea().getCityCode())) {
                predicates.and(qBiddingArea.cityCode.eq(request.getArea().getCityCode()));
            }
            if (StringUtils.hasLength(request.getArea().getProvinceCode())) {
                predicates.and(qBiddingArea.provinceCode.eq(request.getArea().getProvinceCode()));
            }
        }
        JPAQuery<PurchaseListResponse> query = queryFactory.select(Projections.bean(PurchaseListResponse.class,
                qBidding.id,
                qBidding.biddingNo.as("purchaseInquiryNo"),
                qBidding.details,
                qBidding.createTime,
                qBidding.shopIds,
                qBidding.deliver.as("deliveryTime"),
                qBidding.endSignUp.as("offerEndTime"),
                qBidding.address,
                qBidding.addressId,
                qBiddingProduct.id.as("productId"),
                qBiddingProduct.category,
                qBidding.createMemberId.as("memberId"),
                qBidding.createMemberName.as("memberName"),
                qBidding.createMemberRoleId.as("memberRoleId"),
                qBiddingArea.provinceCode,
                qBiddingArea.province,
                qBiddingArea.cityCode,
                qBiddingArea.city,
                qBiddingArea.areaCode,
                qBiddingArea.area
        )).from(qBidding)
                .leftJoin(qBiddingProduct)
                .on(qBidding.id.eq(qBiddingProduct.bidding.id))
                .leftJoin(qBiddingArea)
                .on(qBidding.id.eq(qBiddingArea.bidding.id))
                .where(predicates);
        long totalCount = query.fetchCount();
        responses = query.orderBy(qBidding.createTime.desc())
                .fetch();
        if (!CollectionUtils.isEmpty(responses)) {
            //TODO 查询信用分
        }

        Map<Long, List<PurchaseListResponse>> collect = responses.stream().collect(Collectors.groupingBy(PurchaseListResponse::getId));
        List<PurchaseListResponse> purchaseList = new ArrayList<>();
        for (Long id : collect.keySet()) {
            List<PurchaseListResponse> purchaseListResponses = collect.get(id);
            PurchaseListResponse purchaseListResponse = purchaseListResponses.get(0);
            //适用地市组装
            List<CountryArea> areas = purchaseListResponses.stream().map(PurchaseListResponse::getCountryArea).collect(Collectors.toList());
            purchaseListResponse.setAreas(areas);
            purchaseList.add(purchaseListResponse);
        }
        return Wrapper.success(new PageData<>(totalCount, purchaseList));
    }


    @Override
    public Wrapper<PageData<BiddingListResponse>> awaitShopNewList(BiddingListRequest request, UserLoginCacheDTO sysUser) {
        //设置商城类型为企业商城
        request.setShopType(ShopTypeEnum.ENTERPRISE.getCode());

        Wrapper<PageData<BiddingListResponse>> query = getQuery(sysUser, request, BiddingListEnum.ADD_SHOP_PURCHASE_BIDDING_LIST.getType());
        if (ResponseCode.SUCCESS.getCode() == query.getCode() && query.getData().getTotalCount() > 0) {
            query.getData().getData().forEach(bidding -> {
                if (BiddingInteriorWorkStateEnum.STAY_SUBMIT_BIDDING.getState().equals(bidding.getInteriorState())) {
                    bidding.setButtons(Arrays.asList(BiddingButtonEnums.SUBMIT_REVIEW.getState(), BiddingButtonEnums.UPDATE.getState(), BiddingButtonEnums.DELETE.getState()));
                } else {
                    bidding.setButtons(Collections.singletonList(BiddingButtonEnums.UPDATE.getState()));
                }
            });
        }
        return query;
    }
}
